home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / text / edit / vim60src.lha / Vim / vim60 / src / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-24  |  185.4 KB  |  8,862 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. /*
  11.  * eval.c: Expression evaluation.
  12.  */
  13. #if defined(MSDOS) || defined(MSWIN32) || defined(WIN16) || defined(_WIN64)
  14. # include <io.h>    /* for mch_open(), must be before vim.h */
  15. #endif
  16.  
  17. #include "vim.h"
  18.  
  19. #ifdef AMIGA
  20. # include <time.h>    /* for strftime() */
  21. #endif
  22.  
  23. #ifdef MACOS
  24. # include <time.h>       /* for time_t */
  25. #endif
  26.  
  27. #ifdef HAVE_FCNTL_H
  28. # include <fcntl.h>
  29. #endif
  30.  
  31. #if defined(FEAT_EVAL) || defined(PROTO)
  32.  
  33. #if SIZEOF_INT <= 3        /* use long if int is smaller than 32 bits */
  34. typedef long    varnumber_T;
  35. #else
  36. typedef int    varnumber_T;
  37. #endif
  38.  
  39. /*
  40.  * Structure to hold an internal variable.
  41.  */
  42. typedef struct
  43. {
  44.     char_u    *var_name;    /* name of variable */
  45.     char    var_type;    /* VAR_NUMBER or VAR_STRING */
  46.     union
  47.     {
  48.     varnumber_T    var_number;   /* number value */
  49.     char_u        *var_string;  /* string value (Careful: can be NULL!) */
  50.     } var_val;
  51. } var;
  52.  
  53. #define VAR_UNKNOWN 0
  54. #define VAR_NUMBER  1
  55. #define VAR_STRING  2
  56.  
  57. typedef var *    VAR;
  58.  
  59. /*
  60.  * All user-defined global variables are stored in "variables".
  61.  */
  62. garray_T    variables = {0, 0, sizeof(var), 4, NULL};
  63.  
  64. /*
  65.  * Array to hold an array with variables local to each sourced script.
  66.  */
  67. static garray_T        ga_scripts = {0, 0, sizeof(garray_T), 4, NULL};
  68. #define SCRIPT_VARS(id) (((garray_T *)ga_scripts.ga_data)[(id) - 1])
  69.  
  70.  
  71. #define VAR_ENTRY(idx)    (((VAR)(variables.ga_data))[idx])
  72. #define VAR_GAP_ENTRY(idx, gap)    (((VAR)(gap->ga_data))[idx])
  73. #define BVAR_ENTRY(idx)    (((VAR)(curbuf->b_vars.ga_data))[idx])
  74. #define WVAR_ENTRY(idx)    (((VAR)(curwin->w_vars.ga_data))[idx])
  75.  
  76. static int echo_attr = 0;   /* attributes used for ":echo" */
  77.  
  78. /*
  79.  * Structure to hold info for a user function.
  80.  */
  81. typedef struct ufunc ufunc_T;
  82.  
  83. struct ufunc
  84. {
  85.     ufunc_T    *next;        /* next function in list */
  86.     char_u    *name;        /* name of function; can start with <SNR>123_
  87.                    (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) */
  88.     int        varargs;    /* variable nr of arguments */
  89.     int        flags;
  90.     int        calls;        /* nr of active calls */
  91.     garray_T    args;        /* arguments */
  92.     garray_T    lines;        /* function lines */
  93.     scid_T    script_ID;    /* ID of script where function was defined,
  94.                    used for s: variables */
  95. };
  96.  
  97. /* function flags */
  98. #define FC_ABORT    1        /* abort function on error */
  99. #define FC_RANGE    2        /* function accepts range */
  100.  
  101. /*
  102.  * All user-defined functions are found in the forward-linked function list.
  103.  * The first function is pointed at by firstfunc.
  104.  */
  105. ufunc_T        *firstfunc = NULL;
  106.  
  107. #define FUNCARG(fp, j)    ((char_u **)(fp->args.ga_data))[j]
  108. #define FUNCLINE(fp, j)    ((char_u **)(fp->lines.ga_data))[j]
  109.  
  110. /* structure to hold info for a function that is currently being executed. */
  111. struct funccall
  112. {
  113.     ufunc_T    *func;        /* function being called */
  114.     int        linenr;        /* next line to be executed */
  115.     int        argcount;    /* nr of arguments */
  116.     VAR        argvars;    /* arguments */
  117.     var        a0_var;        /* "a:0" variable */
  118.     var        firstline;    /* "a:firstline" variable */
  119.     var        lastline;    /* "a:lastline" variable */
  120.     garray_T    l_vars;        /* local function variables */
  121.     VAR        retvar;        /* return value variable */
  122.     linenr_T    breakpoint;    /* next line with breakpoint or zero */
  123.     int        dbg_tick;    /* debug_tick when breakpoint was set */
  124. };
  125.  
  126. /* pointer to funccal for currently active function */
  127. struct funccall *current_funccal = NULL;
  128.  
  129. /*
  130.  * Array to hold the value of v: variables.
  131.  */
  132. #include "version.h"
  133.  
  134. /* values for flags: */
  135. #define VV_COMPAT   1        /* compatible, also used without "v:" */
  136. #define VV_RO        2        /* read-only */
  137.  
  138. struct vimvar
  139. {
  140.     char    *name;        /* name of variable, without v: */
  141.     int        len;        /* length of name */
  142.     char_u    *val;        /* current value (can also be a number!) */
  143.     char    type;        /* VAR_NUMBER or VAR_STRING */
  144.     char    flags;        /* VV_COMPAT and VV_RO */
  145. } vimvars[VV_LEN] =
  146. {   /* The order here must match the VV_ defines in vim.h! */
  147.     {"count", sizeof("count") - 1, NULL, VAR_NUMBER, VV_COMPAT+VV_RO},
  148.     {"count1", sizeof("count1") - 1, NULL, VAR_NUMBER, VV_RO},
  149.     {"prevcount", sizeof("prevcount") - 1, NULL, VAR_NUMBER, VV_RO},
  150.     {"errmsg", sizeof("errmsg") - 1, NULL, VAR_STRING, VV_COMPAT},
  151.     {"warningmsg", sizeof("warningmsg") - 1, NULL, VAR_STRING, 0},
  152.     {"statusmsg", sizeof("statusmsg") - 1, NULL, VAR_STRING, 0},
  153.     {"shell_error", sizeof("shell_error") - 1, NULL, VAR_NUMBER,
  154.                                  VV_COMPAT+VV_RO},
  155.     {"this_session", sizeof("this_session") - 1, NULL, VAR_STRING, VV_COMPAT},
  156.     {"version", sizeof("version") - 1, (char_u *)VIM_VERSION_100,
  157.                          VAR_NUMBER, VV_COMPAT+VV_RO},
  158.     {"lnum", sizeof("lnum") - 1, NULL, VAR_NUMBER, VV_RO},
  159.     {"termresponse", sizeof("termresponse") - 1, NULL, VAR_STRING, VV_RO},
  160.     {"fname", sizeof("fname") - 1, NULL, VAR_STRING, VV_RO},
  161.     {"lang", sizeof("lang") - 1, NULL, VAR_STRING, VV_RO},
  162.     {"lc_time", sizeof("lc_time") - 1, NULL, VAR_STRING, VV_RO},
  163.     {"ctype", sizeof("ctype") - 1, NULL, VAR_STRING, VV_RO},
  164.     {"charconvert_from", sizeof("charconvert_from") - 1, NULL, VAR_STRING, VV_RO},
  165.     {"charconvert_to", sizeof("charconvert_to") - 1, NULL, VAR_STRING, VV_RO},
  166.     {"fname_in", sizeof("fname_in") - 1, NULL, VAR_STRING, VV_RO},
  167.     {"fname_out", sizeof("fname_out") - 1, NULL, VAR_STRING, VV_RO},
  168.     {"fname_new", sizeof("fname_new") - 1, NULL, VAR_STRING, VV_RO},
  169.     {"fname_diff", sizeof("fname_diff") - 1, NULL, VAR_STRING, VV_RO},
  170.     {"cmdarg", sizeof("cmdarg") - 1, NULL, VAR_STRING, VV_RO},
  171.     {"foldstart", sizeof("foldstart") - 1, NULL, VAR_NUMBER, VV_RO},
  172.     {"foldend", sizeof("foldend") - 1, NULL, VAR_NUMBER, VV_RO},
  173.     {"folddashes", sizeof("folddashes") - 1, NULL, VAR_STRING, VV_RO},
  174.     {"foldlevel", sizeof("foldlevel") - 1, NULL, VAR_NUMBER, VV_RO},
  175.     {"progname", sizeof("progname") - 1, NULL, VAR_STRING, VV_RO},
  176.     {"servername", sizeof("servername") - 1, NULL, VAR_STRING, VV_RO},
  177. };
  178.  
  179. static int eval0 __ARGS((char_u *arg,  VAR retvar, char_u **nextcmd, int evaluate));
  180. static int eval1 __ARGS((char_u **arg, VAR retvar, int evaluate));
  181. static int eval2 __ARGS((char_u **arg, VAR retvar, int evaluate));
  182. static int eval3 __ARGS((char_u **arg, VAR retvar, int evaluate));
  183. static int eval4 __ARGS((char_u **arg, VAR retvar, int evaluate));
  184. static int eval5 __ARGS((char_u **arg, VAR retvar, int evaluate));
  185. static int eval6 __ARGS((char_u **arg, VAR retvar, int evaluate));
  186. static int eval7 __ARGS((char_u **arg, VAR retvar, int evaluate));
  187. static int get_option_var __ARGS((char_u **arg, VAR retvar, int evaluate));
  188. static int get_string_var __ARGS((char_u **arg, VAR retvar, int evaluate));
  189. static int get_lit_string_var __ARGS((char_u **arg, VAR retvar, int evaluate));
  190. static int get_env_var __ARGS((char_u **arg, VAR retvar, int evaluate));
  191. static int find_internal_func __ARGS((char_u *name));
  192. static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate));
  193. static void f_append __ARGS((VAR argvars, VAR retvar));
  194. static void f_argc __ARGS((VAR argvars, VAR retvar));
  195. static void f_argidx __ARGS((VAR argvars, VAR retvar));
  196. static void f_argv __ARGS((VAR argvars, VAR retvar));
  197. static void f_browse __ARGS((VAR argvars, VAR retvar));
  198. static buf_T *find_buffer __ARGS((VAR avar));
  199. static void f_bufexists __ARGS((VAR argvars, VAR retvar));
  200. static void f_buflisted __ARGS((VAR argvars, VAR retvar));
  201. static void f_bufloaded __ARGS((VAR argvars, VAR retvar));
  202. static buf_T *get_buf_var __ARGS((VAR avar));
  203. static void f_bufname __ARGS((VAR argvars, VAR retvar));
  204. static void f_bufnr __ARGS((VAR argvars, VAR retvar));
  205. static void f_bufwinnr __ARGS((VAR argvars, VAR retvar));
  206. static void f_byte2line __ARGS((VAR argvars, VAR retvar));
  207. static void f_char2nr __ARGS((VAR argvars, VAR retvar));
  208. static void f_cindent __ARGS((VAR argvars, VAR retvar));
  209. static void f_col __ARGS((VAR argvars, VAR retvar));
  210. static void f_confirm __ARGS((VAR argvars, VAR retvar));
  211. static void f_cscope_connection __ARGS((VAR argvars, VAR retvar));
  212. static void f_delete __ARGS((VAR argvars, VAR retvar));
  213. static void f_inputdialog __ARGS((VAR argvars, VAR retvar));
  214. static void f_did_filetype __ARGS((VAR argvars, VAR retvar));
  215. static void f_escape __ARGS((VAR argvars, VAR retvar));
  216. static void f_eventhandler __ARGS((VAR argvars, VAR retvar));
  217. static void f_executable __ARGS((VAR argvars, VAR retvar));
  218. static void f_exists __ARGS((VAR argvars, VAR retvar));
  219. static void f_expand __ARGS((VAR argvars, VAR retvar));
  220. static void f_filereadable __ARGS((VAR argvars, VAR retvar));
  221. static void f_filewritable __ARGS((VAR argvars, VAR retvar));
  222. static void f_fnamemodify __ARGS((VAR argvars, VAR retvar));
  223. static void f_foldclosed __ARGS((VAR argvars, VAR retvar));
  224. static void f_foldclosedend __ARGS((VAR argvars, VAR retvar));
  225. static void foldclosed_both __ARGS((VAR argvars, VAR retvar, int end));
  226. static void f_foldlevel __ARGS((VAR argvars, VAR retvar));
  227. static void f_foldtext __ARGS((VAR argvars, VAR retvar));
  228. static void f_foreground __ARGS((VAR argvars, VAR retvar));
  229. static void f_getbufvar __ARGS((VAR argvars, VAR retvar));
  230. static void f_getchar __ARGS((VAR argvars, VAR retvar));
  231. static void f_getcharmod __ARGS((VAR argvars, VAR retvar));
  232. static void f_getwinvar __ARGS((VAR argvars, VAR retvar));
  233. static void f_getcwd __ARGS((VAR argvars, VAR retvar));
  234. static void f_getftime __ARGS((VAR argvars, VAR retvar));
  235. static void f_getfsize __ARGS((VAR argvars, VAR retvar));
  236. static void f_getline __ARGS((VAR argvars, VAR retvar));
  237. static void f_getwinposx __ARGS((VAR argvars, VAR retvar));
  238. static void f_getwinposy __ARGS((VAR argvars, VAR retvar));
  239. static void f_glob __ARGS((VAR argvars, VAR retvar));
  240. static void f_globpath __ARGS((VAR argvars, VAR retvar));
  241. static void f_has __ARGS((VAR argvars, VAR retvar));
  242. static void f_hasmapto __ARGS((VAR argvars, VAR retvar));
  243. static void f_histadd __ARGS((VAR argvars, VAR retvar));
  244. static void f_histdel __ARGS((VAR argvars, VAR retvar));
  245. static void f_histget __ARGS((VAR argvars, VAR retvar));
  246. static void f_histnr __ARGS((VAR argvars, VAR retvar));
  247. static void f_hlexists __ARGS((VAR argvars, VAR retvar));
  248. static void f_hlID __ARGS((VAR argvars, VAR retvar));
  249. static void f_hostname __ARGS((VAR argvars, VAR retvar));
  250. static void f_iconv __ARGS((VAR argvars, VAR retvar));
  251. static void f_indent __ARGS((VAR argvars, VAR retvar));
  252. static void f_isdirectory __ARGS((VAR argvars, VAR retvar));
  253. static void f_input __ARGS((VAR argvars, VAR retvar));
  254. static void f_inputsecret __ARGS((VAR argvars, VAR retvar));
  255. static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar));
  256. static void f_libcall __ARGS((VAR argvars, VAR retvar));
  257. static void f_libcallnr __ARGS((VAR argvars, VAR retvar));
  258. static void libcall_common __ARGS((VAR argvars, VAR retvar, int type));
  259. static void f_line __ARGS((VAR argvars, VAR retvar));
  260. static void f_line2byte __ARGS((VAR argvars, VAR retvar));
  261. static void f_lispindent __ARGS((VAR argvars, VAR retvar));
  262. static void f_localtime __ARGS((VAR argvars, VAR retvar));
  263. static void f_maparg __ARGS((VAR argvars, VAR retvar));
  264. static void f_mapcheck __ARGS((VAR argvars, VAR retvar));
  265. static void get_maparg __ARGS((VAR argvars, VAR retvar, int exact));
  266. static void f_match __ARGS((VAR argvars, VAR retvar));
  267. static void f_matchend __ARGS((VAR argvars, VAR retvar));
  268. static void f_matchstr __ARGS((VAR argvars, VAR retvar));
  269. static void f_mode __ARGS((VAR argvars, VAR retvar));
  270. static void f_nextnonblank __ARGS((VAR argvars, VAR retvar));
  271. static void f_nr2char __ARGS((VAR argvars, VAR retvar));
  272. static void f_prevnonblank __ARGS((VAR argvars, VAR retvar));
  273. static void f_setbufvar __ARGS((VAR argvars, VAR retvar));
  274. static void f_setwinvar __ARGS((VAR argvars, VAR retvar));
  275. static void f_rename __ARGS((VAR argvars, VAR retvar));
  276. static void f_resolve __ARGS((VAR argvars, VAR retvar));
  277. static void f_search __ARGS((VAR argvars, VAR retvar));
  278. static void f_searchpair __ARGS((VAR argvars, VAR retvar));
  279. static int get_search_arg __ARGS((VAR varp, int *flagsp));
  280. static void f_remote_expr __ARGS((VAR argvars, VAR retvar));
  281. static void f_remote_foreground __ARGS((VAR argvars, VAR retvar));
  282. static void f_remote_peek __ARGS((VAR argvars, VAR retvar));
  283. static void f_remote_read __ARGS((VAR argvars, VAR retvar));
  284. static void f_remote_send __ARGS((VAR argvars, VAR retvar));
  285. static void f_server2client __ARGS((VAR argvars, VAR retvar));
  286. static void f_serverlist __ARGS((VAR argvars, VAR retvar));
  287. static void f_setline __ARGS((VAR argvars, VAR retvar));
  288. static void find_some_match __ARGS((VAR argvars, VAR retvar, int start));
  289. static void f_strftime __ARGS((VAR argvars, VAR retvar));
  290. static void f_stridx __ARGS((VAR argvars, VAR retvar));
  291. static void f_strlen __ARGS((VAR argvars, VAR retvar));
  292. static void f_strpart __ARGS((VAR argvars, VAR retvar));
  293. static void f_strridx __ARGS((VAR argvars, VAR retvar));
  294. static void f_strtrans __ARGS((VAR argvars, VAR retvar));
  295. static void f_synID __ARGS((VAR argvars, VAR retvar));
  296. static void f_synIDattr __ARGS((VAR argvars, VAR retvar));
  297. static void f_synIDtrans __ARGS((VAR argvars, VAR retvar));
  298. static void f_system __ARGS((VAR argvars, VAR retvar));
  299. static void f_submatch __ARGS((VAR argvars, VAR retvar));
  300. static void f_substitute __ARGS((VAR argvars, VAR retvar));
  301. static void f_tempname __ARGS((VAR argvars, VAR retvar));
  302. static void f_tolower __ARGS((VAR argvars, VAR retvar));
  303. static void f_toupper __ARGS((VAR argvars, VAR retvar));
  304. static void f_type __ARGS((VAR argvars, VAR retvar));
  305. static void f_virtcol __ARGS((VAR argvars, VAR retvar));
  306. static void f_visualmode __ARGS((VAR argvars, VAR retvar));
  307. static void f_winbufnr __ARGS((VAR argvars, VAR retvar));
  308. static void f_wincol __ARGS((VAR argvars, VAR retvar));
  309. static void f_winheight __ARGS((VAR argvars, VAR retvar));
  310. static void f_winline __ARGS((VAR argvars, VAR retvar));
  311. static void f_winnr __ARGS((VAR argvars, VAR retvar));
  312. static void f_winwidth __ARGS((VAR argvars, VAR retvar));
  313. static win_T *find_win_by_nr __ARGS((VAR vp));
  314. static pos_T *var2fpos __ARGS((VAR varp, int lnum));
  315. static int get_env_len __ARGS((char_u **arg));
  316. static int get_id_len __ARGS((char_u **arg));
  317. static int get_func_len __ARGS((char_u **arg, char_u **alias));
  318. static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end));
  319. static int eval_isnamec __ARGS((int c));
  320. static int find_vim_var __ARGS((char_u *name, int len));
  321. static int get_var_var __ARGS((char_u *name, int len, VAR retvar));
  322. static VAR alloc_var __ARGS((void));
  323. static VAR alloc_string_var __ARGS((char_u *string));
  324. static void free_var __ARGS((VAR varp));
  325. static void clear_var __ARGS((VAR varp));
  326. static long get_var_number __ARGS((VAR varp));
  327. static linenr_T get_var_lnum __ARGS((VAR argvars));
  328. static char_u *get_var_string __ARGS((VAR varp));
  329. static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf));
  330. static VAR find_var __ARGS((char_u *name, int writing));
  331. static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname));
  332. static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname));
  333. static void var_free_one __ARGS((VAR v));
  334. static void list_one_var __ARGS((VAR v, char_u *prefix));
  335. static void list_vim_var __ARGS((int i));
  336. static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
  337. static void set_var __ARGS((char_u *name, VAR varp));
  338. static void copy_var __ARGS((VAR from, VAR to));
  339. static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
  340. static char_u *trans_function_name __ARGS((char_u **pp));
  341. static int eval_fname_script __ARGS((char_u *p));
  342. static int eval_fname_sid __ARGS((char_u *p));
  343. static void list_func_head __ARGS((ufunc_T *fp));
  344. static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
  345. static ufunc_T *find_func __ARGS((char_u *name));
  346. static void call_func __ARGS((ufunc_T *fp, int argcount, VAR argvars, VAR retvar, linenr_T firstline, linenr_T lastline));
  347.  
  348. #define FEAT_MAGIC_BRACES
  349.  
  350. #ifdef FEAT_MAGIC_BRACES
  351. static char_u * make_expanded_name __ARGS((char_u *in_start,  char_u *expr_start,  char_u *expr_end,  char_u *in_end));
  352. #endif
  353.  
  354. #if defined(FEAT_STL_OPT) || defined(PROTO)
  355. /*
  356.  * Set an internal variable to a string value. Creates the variable if it does
  357.  * not already exist.
  358.  */
  359.     void
  360. set_internal_string_var(name, value)
  361.     char_u    *name;
  362.     char_u    *value;
  363. {
  364.     char_u  *val;
  365.     VAR        varp;
  366.  
  367.     val = vim_strsave(value);
  368.     if (val != NULL)
  369.     {
  370.     varp = alloc_string_var(val);
  371.     if (varp != NULL)
  372.     {
  373.         set_var(name, varp);
  374.         free_var(varp);
  375.     }
  376.     }
  377. }
  378. #endif
  379.  
  380. /*
  381.  * Top level evaluation function, returning a boolean.
  382.  * Sets "error" to TRUE if there was an error.
  383.  * Return TRUE or FALSE.
  384.  */
  385.     int
  386. eval_to_bool(arg, error, nextcmd, skip)
  387.     char_u    *arg;
  388.     int        *error;
  389.     char_u    **nextcmd;
  390.     int        skip;        /* only parse, don't execute */
  391. {
  392.     var        retvar;
  393.     int        retval = FALSE;
  394.  
  395.     if (skip)
  396.     ++emsg_skip;
  397.     if (eval0(arg, &retvar, nextcmd, !skip) == FAIL)
  398.     {
  399.     *error = TRUE;
  400.     }
  401.     else if (!skip)
  402.     {
  403.     *error = FALSE;
  404.     retval = (get_var_number(&retvar) != 0);
  405.     clear_var(&retvar);
  406.     }
  407.     if (skip)
  408.     --emsg_skip;
  409.  
  410.     return retval;
  411. }
  412.  
  413. /*
  414.  * Top level evaluation function, returning a string.
  415.  * Return pointer to allocated memory, or NULL for failure.
  416.  */
  417.     char_u *
  418. eval_to_string(arg, nextcmd)
  419.     char_u    *arg;
  420.     char_u    **nextcmd;
  421. {
  422.     var        retvar;
  423.     char_u    *retval;
  424.  
  425.     if (eval0(arg, &retvar, nextcmd, TRUE) == FAIL)
  426.     retval = NULL;
  427.     else
  428.     {
  429.     retval = vim_strsave(get_var_string(&retvar));
  430.     clear_var(&retvar);
  431.     }
  432.  
  433.     return retval;
  434. }
  435.  
  436. /*
  437.  * Call eval_to_string() with "sandbox" set and not using local variables.
  438.  */
  439.     char_u *
  440. eval_to_string_safe(arg, nextcmd)
  441.     char_u    *arg;
  442.     char_u    **nextcmd;
  443. {
  444.     char_u    *retval;
  445.     void    *save_funccalp;
  446.  
  447.     save_funccalp = save_funccal();
  448.     ++sandbox;
  449.     retval = eval_to_string(arg, nextcmd);
  450.     --sandbox;
  451.     restore_funccal(save_funccalp);
  452.     return retval;
  453. }
  454.  
  455. #if 0 /* not used */
  456. /*
  457.  * Top level evaluation function, returning a string.
  458.  * Advances "arg" to the first non-blank after the evaluated expression.
  459.  * Return pointer to allocated memory, or NULL for failure.
  460.  * Doesn't give error messages.
  461.  */
  462.     char_u *
  463. eval_arg_to_string(arg)
  464.     char_u    **arg;
  465. {
  466.     var        retvar;
  467.     char_u    *retval;
  468.     int        ret;
  469.  
  470.     ++emsg_off;
  471.  
  472.     ret = eval1(arg, &retvar, TRUE);
  473.     if (ret == FAIL)
  474.     retval = NULL;
  475.     else
  476.     {
  477.     retval = vim_strsave(get_var_string(&retvar));
  478.     clear_var(&retvar);
  479.     }
  480.  
  481.     --emsg_off;
  482.  
  483.     return retval;
  484. }
  485. #endif
  486.  
  487. /*
  488.  * Top level evaluation function, returning a number.
  489.  * Evaluates "expr" silently.
  490.  * Returns -1 for an error.
  491.  */
  492.     int
  493. eval_to_number(expr)
  494.     char_u    *expr;
  495. {
  496.     var        retvar;
  497.     int        retval;
  498.     char_u    *p = expr;
  499.  
  500.     ++emsg_off;
  501.  
  502.     if (eval1(&p, &retvar, TRUE) == FAIL)
  503.     retval = -1;
  504.     else
  505.     {
  506.     retval = get_var_number(&retvar);
  507.     clear_var(&retvar);
  508.     }
  509.     --emsg_off;
  510.  
  511.     return retval;
  512. }
  513.  
  514. #ifdef FEAT_FOLDING
  515. /*
  516.  * Evaluate 'foldexpr'.  Returns the foldlevel, and any character preceding
  517.  * it in "*cp".  Doesn't give error messages.
  518.  */
  519.     int
  520. eval_foldexpr(arg, cp)
  521.     char_u    *arg;
  522.     int        *cp;
  523. {
  524.     var        retvar;
  525.     int        retval;
  526.     char_u    *s;
  527.  
  528.     ++emsg_off;
  529.     ++sandbox;
  530.     *cp = NUL;
  531.     if (eval0(arg, &retvar, NULL, TRUE) == FAIL)
  532.     retval = 0;
  533.     else
  534.     {
  535.     /* If the result is a number, just return the number. */
  536.     if (retvar.var_type == VAR_NUMBER)
  537.         retval = retvar.var_val.var_number;
  538.     else if (retvar.var_type == VAR_UNKNOWN
  539.         || retvar.var_val.var_string == NULL)
  540.         retval = 0;
  541.     else
  542.     {
  543.         /* If the result is a string, check if there is a non-digit before
  544.          * the number. */
  545.         s = retvar.var_val.var_string;
  546.         if (!isdigit(*s) && *s != '-')
  547.         *cp = *s++;
  548.         retval = atol((char *)s);
  549.     }
  550.     clear_var(&retvar);
  551.     }
  552.     --emsg_off;
  553.     --sandbox;
  554.  
  555.     return retval;
  556. }
  557. #endif
  558.  
  559. #ifdef FEAT_MAGIC_BRACES
  560. /*
  561.  * Expands out the 'magic' {}'s in a variable/function name.
  562.  * Note that this can call itself recursively, to deal with
  563.  * constructs like foo{bar}{baz}{bam}
  564.  * The four pointer arguments point to "foo{expre}ss{ion}bar"
  565.  *            "in_start"      ^
  566.  *            "expr_start"       ^
  567.  *            "expr_end"         ^
  568.  *            "in_end"                ^
  569.  *
  570.  * Returns a new allocated string, which the caller must free.
  571.  * Returns NULL for failure.
  572.  */
  573.     static char_u *
  574. make_expanded_name(in_start, expr_start, expr_end, in_end)
  575.     char_u    *in_start;
  576.     char_u    *expr_start;
  577.     char_u    *expr_end;
  578.     char_u    *in_end;
  579. {
  580.     char_u    c1;
  581.     char_u    *retval = NULL;
  582.     char_u    *temp_result;
  583.  
  584.     if (expr_end == NULL || in_end == NULL)
  585.     return NULL;
  586.     *expr_start    = NUL;
  587.     *expr_end = NUL;
  588.     c1 = *in_end;
  589.     *in_end = NUL;
  590.  
  591.     temp_result = eval_to_string(expr_start + 1, NULL);
  592.     if (temp_result != NULL)
  593.     {
  594.     retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
  595.                            + (in_end - expr_end) + 1));
  596.  
  597.     if (retval != NULL)
  598.     {
  599.         STRCPY(retval, in_start);
  600.         STRCAT(retval, temp_result);
  601.         STRCAT(retval, expr_end + 1);
  602.     }
  603.  
  604.     vim_free(temp_result);
  605.     }
  606.  
  607.     *in_end = c1;        /* put char back for error messages */
  608.     *expr_start = '{';
  609.     *expr_end = '}';
  610.  
  611.     if (retval != NULL)
  612.     {
  613.     temp_result = find_name_end(retval, &expr_start, &expr_end);
  614.     if (expr_start != NULL)
  615.     {
  616.         /* Further expansion! */
  617.         temp_result = make_expanded_name(retval, expr_start,
  618.                                expr_end, temp_result);
  619.         vim_free(retval);
  620.         retval = temp_result;
  621.     }
  622.     }
  623.  
  624.     return retval;
  625.  
  626. }
  627. #endif /* FEAT_MAGIC_BRACES */
  628.  
  629. /*
  630.  * ":let var = expr"    assignment command.
  631.  * ":let var"        list one variable value
  632.  * ":let"        list all variable values
  633.  */
  634.     void
  635. ex_let(eap)
  636.     exarg_T    *eap;
  637. {
  638.     char_u    *arg = eap->arg;
  639.     char_u    *expr;
  640.     char_u    *name;
  641.     VAR        varp;
  642.     var        retvar;
  643.     char_u    *p;
  644.     int        c1, c2;
  645.     int        i;
  646.  
  647.     expr = vim_strchr(arg, '=');
  648.     if (expr == NULL)
  649.     {
  650.     if (ends_excmd(*arg))
  651.     {
  652.         if (!eap->skip)
  653.         {
  654.         /*
  655.          * List all variables.
  656.          */
  657.         for (i = 0; i < variables.ga_len; ++i)
  658.             if (VAR_ENTRY(i).var_name != NULL)
  659.             list_one_var(&VAR_ENTRY(i), (char_u *)"");
  660.         for (i = 0; i < curbuf->b_vars.ga_len; ++i)
  661.             if (BVAR_ENTRY(i).var_name != NULL)
  662.             list_one_var(&BVAR_ENTRY(i), (char_u *)"b:");
  663.         for (i = 0; i < curwin->w_vars.ga_len; ++i)
  664.             if (WVAR_ENTRY(i).var_name != NULL)
  665.             list_one_var(&WVAR_ENTRY(i), (char_u *)"w:");
  666.         for (i = 0; i < VV_LEN; ++i)
  667.             if (vimvars[i].type == VAR_NUMBER || vimvars[i].val != NULL)
  668.             list_vim_var(i);
  669.         }
  670.     }
  671.     else
  672.     {
  673.         /*
  674.          * List variables.
  675.          */
  676.         while (!ends_excmd(*arg))
  677.         {
  678.         for (p = arg; eval_isnamec(*p); ++p)
  679.             ;
  680.         if (!vim_iswhite(*p) && !ends_excmd(*p))
  681.         {
  682.             EMSG(_(e_trailing));
  683.             break;
  684.         }
  685.         if (!eap->skip)
  686.         {
  687.             c1 = *p;
  688.             *p = NUL;
  689.             i = find_vim_var(arg, (int)(p - arg));
  690.             if (i >= 0)
  691.             list_vim_var(i);
  692.             else
  693.             {
  694.             varp = find_var(arg, FALSE);
  695.             if (varp == NULL)
  696.                 EMSG2(_("E106: Unknown variable: \"%s\""), arg);
  697.             else
  698.             {
  699.                 name = vim_strchr(arg, ':');
  700.                 if (name != NULL)
  701.                 {
  702.                 /* "a:" vars have no name stored, use whole
  703.                  * arg */
  704.                 if (arg[0] == 'a' && arg[1] == ':')
  705.                     c2 = NUL;
  706.                 else
  707.                 {
  708.                     c2 = *++name;
  709.                     *name = NUL;
  710.                 }
  711.                 list_one_var(varp, arg);
  712.                 if (c2 != NUL)
  713.                     *name = c2;
  714.                 }
  715.                 else
  716.                 list_one_var(varp, (char_u *)"");
  717.             }
  718.             }
  719.             *p = c1;
  720.         }
  721.         arg = skipwhite(p);
  722.         }
  723.     }
  724.     eap->nextcmd = check_nextcmd(arg);
  725.     }
  726.     else
  727.     {
  728.     if (eap->skip)
  729.         ++emsg_skip;
  730.     i = eval0(expr + 1, &retvar, &eap->nextcmd, !eap->skip);
  731.     if (eap->skip)
  732.     {
  733.         if (i != FAIL)
  734.         clear_var(&retvar);
  735.         --emsg_skip;
  736.     }
  737.     else if (i != FAIL)
  738.     {
  739.         /*
  740.          * ":let $VAR = expr": Set environment variable.
  741.          */
  742.         if (*arg == '$')
  743.         {
  744.         int    len;
  745.         int    cc;
  746.  
  747.         /* Find the end of the name. */
  748.         ++arg;
  749.         name = arg;
  750.         len = get_env_len(&arg);
  751.         if (len == 0)
  752.             EMSG2(_(e_invarg2), name - 1);
  753.         else
  754.         {
  755.             if (*skipwhite(arg) != '=')
  756.             EMSG(_(e_letunexp));
  757.             else
  758.             {
  759.             cc = name[len];
  760.             name[len] = NUL;
  761.             p = get_var_string(&retvar);
  762.             vim_setenv(name, p);
  763.             if (STRICMP(name, "HOME") == 0)
  764.                 init_homedir();
  765.             else if (didset_vim && STRICMP(name, "VIM") == 0)
  766.                 didset_vim = FALSE;
  767.             else if (didset_vimruntime
  768.                       && STRICMP(name, "VIMRUNTIME") == 0)
  769.                 didset_vimruntime = FALSE;
  770.             name[len] = cc;
  771.             }
  772.         }
  773.         }
  774.  
  775.         /*
  776.          * ":let &option = expr": Set option value.
  777.          * ":let &l:option = expr": Set local option value.
  778.          * ":let &g:option = expr": Set global option value.
  779.          */
  780.         else if (*arg == '&')
  781.         {
  782.         int opt_flags;
  783.  
  784.         /*
  785.          * Find the end of the name;
  786.          */
  787.         p = find_option_end(&arg, &opt_flags);
  788.         if (p == NULL || *skipwhite(p) != '=')
  789.             EMSG(_(e_letunexp));
  790.         else
  791.         {
  792.             c1 = *p;
  793.             *p = NUL;
  794.             set_option_value(arg, get_var_number(&retvar),
  795.                       get_var_string(&retvar), opt_flags);
  796.             *p = c1;            /* put back for error messages */
  797.         }
  798.         }
  799.  
  800.         /*
  801.          * ":let @r = expr": Set register contents.
  802.          */
  803.         else if (*arg == '@')
  804.         {
  805.         ++arg;
  806.         if (*skipwhite(arg + 1) != '=')
  807.             EMSG(_(e_letunexp));
  808.         else
  809.             write_reg_contents(*arg == '@' ? '"' : *arg,
  810.                           get_var_string(&retvar), FALSE);
  811.         }
  812.  
  813.         /*
  814.          * ":let var = expr": Set internal variable.
  815.          */
  816.         else if (eval_isnamec(*arg) && !isdigit(*arg))
  817.         {
  818.         char_u *expr_start;
  819.         char_u *expr_end;
  820.  
  821.         /* Find the end of the name. */
  822.         p = find_name_end(arg, &expr_start, &expr_end);
  823.  
  824.         if (*skipwhite(p) != '=')
  825.             EMSG(_(e_letunexp));
  826. #ifdef FEAT_MAGIC_BRACES
  827.         else if (expr_start != NULL)
  828.         {
  829.             char_u  *temp_string;
  830.  
  831.             temp_string = make_expanded_name(arg, expr_start,
  832.                                  expr_end, p);
  833.             if (temp_string == NULL)
  834.             EMSG2(_(e_invarg2), arg);
  835.             else
  836.             {
  837.             set_var(temp_string, &retvar);
  838.             vim_free(temp_string);
  839.             }
  840.         }
  841. #endif
  842.         else
  843.         {
  844.             c1 = *p;
  845.             *p = NUL;
  846.             set_var(arg, &retvar);
  847.             *p = c1;        /* put char back for error messages */
  848.         }
  849.         }
  850.  
  851.         else
  852.         {
  853.         EMSG2(_(e_invarg2), arg);
  854.         }
  855.  
  856.         clear_var(&retvar);
  857.     }
  858.     }
  859. }
  860.  
  861. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  862.  
  863.     void
  864. set_context_for_expression(xp, arg, cmdidx)
  865.     expand_T    *xp;
  866.     char_u    *arg;
  867.     cmdidx_T    cmdidx;
  868. {
  869.     int        got_eq = FALSE;
  870.     int        c;
  871.  
  872.     xp->xp_context = cmdidx == CMD_let ? EXPAND_USER_VARS
  873.                        : cmdidx == CMD_call ? EXPAND_FUNCTIONS
  874.                        : EXPAND_EXPRESSION;
  875.     while ((xp->xp_pattern = vim_strpbrk(arg,
  876.                   (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
  877.     {
  878.     c = *xp->xp_pattern;
  879.     if (c == '&')
  880.     {
  881.         c = xp->xp_pattern[1];
  882.         if (c == '&')
  883.         {
  884.         ++xp->xp_pattern;
  885.         xp->xp_context = cmdidx != CMD_let || got_eq
  886.                      ? EXPAND_EXPRESSION : EXPAND_NOTHING;
  887.         }
  888.         else if (c != ' ')
  889.         xp->xp_context = EXPAND_SETTINGS;
  890.     }
  891.     else if (c == '$')
  892.     {
  893.         /* environment variable */
  894.         xp->xp_context = EXPAND_ENV_VARS;
  895.     }
  896.     else if (c == '=')
  897.     {
  898.         got_eq = TRUE;
  899.         xp->xp_context = EXPAND_EXPRESSION;
  900.     }
  901.     else if (c == '<'
  902.         && xp->xp_context == EXPAND_FUNCTIONS
  903.         && vim_strchr(xp->xp_pattern, '(') == NULL)
  904.     {
  905.         /* Function name can start with "<SNR>" */
  906.         break;
  907.     }
  908.     else if (cmdidx != CMD_let || got_eq)
  909.     {
  910.         if (c == '"')        /* string */
  911.         {
  912.         while ((c = *++xp->xp_pattern) != NUL && c != '"')
  913.             if (c == '\\' && xp->xp_pattern[1] != NUL)
  914.             ++xp->xp_pattern;
  915.         xp->xp_context = EXPAND_NOTHING;
  916.         }
  917.         else if (c == '\'')        /* literal string */
  918.         {
  919.         while ((c = *++xp->xp_pattern) != NUL && c != '\'')
  920.             /* skip */ ;
  921.         xp->xp_context = EXPAND_NOTHING;
  922.         }
  923.         else if (c == '|')
  924.         {
  925.         if (xp->xp_pattern[1] == '|')
  926.         {
  927.             ++xp->xp_pattern;
  928.             xp->xp_context = EXPAND_EXPRESSION;
  929.         }
  930.         else
  931.             xp->xp_context = EXPAND_COMMANDS;
  932.         }
  933.         else
  934.         xp->xp_context = EXPAND_EXPRESSION;
  935.     }
  936.     else
  937.         xp->xp_context = EXPAND_NOTHING;
  938.     arg = xp->xp_pattern;
  939.     if (*arg != NUL)
  940.         while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
  941.         /* skip */ ;
  942.     }
  943.     xp->xp_pattern = arg;
  944. }
  945.  
  946. #endif /* FEAT_CMDL_COMPL */
  947.  
  948. /*
  949.  * ":1,25call func(arg1, arg2)"    function call.
  950.  */
  951.     void
  952. ex_call(eap)
  953.     exarg_T    *eap;
  954. {
  955.     char_u    *arg = eap->arg;
  956.     char_u    *startarg;
  957.     char_u    *alias;
  958.     char_u    *name;
  959.     var        retvar;
  960.     int        len;
  961.     linenr_T    lnum;
  962.     int        doesrange;
  963.     int        failed = FALSE;
  964.  
  965.     name = arg;
  966.     len = get_func_len(&arg, &alias);
  967.     if (alias != NULL)
  968.     name = alias;
  969.  
  970.     startarg = arg;
  971.     retvar.var_type = VAR_UNKNOWN;    /* clear_var() uses this */
  972.  
  973.     if (*startarg != '(')
  974.     {
  975.     EMSG2(_("E107: Missing braces: %s"), name);
  976.     goto end;
  977.     }
  978.  
  979.     /*
  980.      * When skipping, evaluate the function once, to find the end of the
  981.      * arguments.
  982.      * When the function takes a range, this is discovered after the first
  983.      * call, and the loop is broken.
  984.      */
  985.     if (eap->skip)
  986.     ++emsg_skip;
  987.     for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
  988.     {
  989.     if (!eap->skip && eap->addr_count > 0)
  990.     {
  991.         curwin->w_cursor.lnum = lnum;
  992.         curwin->w_cursor.col = 0;
  993.     }
  994.     arg = startarg;
  995.     if (get_func_var(name, len, &retvar, &arg,
  996.               eap->line1, eap->line2, &doesrange, !eap->skip) == FAIL)
  997.     {
  998.         failed = TRUE;
  999.         break;
  1000.     }
  1001.     clear_var(&retvar);
  1002.     if (doesrange || eap->skip)
  1003.         break;
  1004.     }
  1005.     if (eap->skip)
  1006.     --emsg_skip;
  1007.  
  1008.     if (!failed)
  1009.     {
  1010.     /* Check for trailing illegal characters and a following command. */
  1011.     if (!ends_excmd(*arg))
  1012.         EMSG(_(e_trailing));
  1013.     else
  1014.         eap->nextcmd = check_nextcmd(arg);
  1015.     }
  1016.  
  1017. end:
  1018.     if (alias != NULL)
  1019.     vim_free(alias);
  1020.  
  1021. }
  1022.  
  1023. /*
  1024.  * ":unlet[!] var1 ... " command.
  1025.  */
  1026.     void
  1027. ex_unlet(eap)
  1028.     exarg_T    *eap;
  1029. {
  1030.     char_u    *arg = eap->arg;
  1031.     char_u    *name_end;
  1032.     char_u    cc;
  1033.  
  1034.     do
  1035.     {
  1036.     name_end = skiptowhite(arg);
  1037.     cc = *name_end;
  1038.     *name_end = NUL;
  1039.  
  1040.     if (do_unlet(arg) == FAIL && !eap->forceit)
  1041.     {
  1042.         *name_end = cc;
  1043.         EMSG2(_("E108: No such variable: \"%s\""), arg);
  1044.         break;
  1045.     }
  1046.  
  1047.     *name_end = cc;
  1048.     arg = skipwhite(name_end);
  1049.     } while (*arg != NUL);
  1050. }
  1051.  
  1052. /*
  1053.  * "unlet" a variable.  Return OK if it existed, FAIL if not.
  1054.  */
  1055.     int
  1056. do_unlet(name)
  1057.     char_u    *name;
  1058. {
  1059.     VAR        v;
  1060.  
  1061.     v = find_var(name, TRUE);
  1062.     if (v != NULL)
  1063.     {
  1064.     var_free_one(v);
  1065.     return OK;
  1066.     }
  1067.     return FAIL;
  1068. }
  1069.  
  1070. #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
  1071. /*
  1072.  * Delete all "menutrans_" variables.
  1073.  */
  1074.     void
  1075. del_menutrans_vars()
  1076. {
  1077.     int        i;
  1078.  
  1079.     for (i = 0; i < variables.ga_len; ++i)
  1080.     if (VAR_ENTRY(i).var_name != NULL
  1081.         && STRNCMP(VAR_ENTRY(i).var_name, "menutrans_", 10) == 0)
  1082.         var_free_one(&VAR_ENTRY(i));
  1083. }
  1084. #endif
  1085.  
  1086. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  1087.  
  1088. /*
  1089.  * Local string buffer for the next two functions to store a variable name
  1090.  * with its prefix. Allocated in cat_prefix_varname(), freed later in
  1091.  * get_user_var_name().
  1092.  */
  1093.  
  1094. static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name));
  1095.  
  1096. static char_u    *varnamebuf = NULL;
  1097. static int    varnamebuflen = 0;
  1098.  
  1099. /*
  1100.  * Function to concatenate a prefix and a variable name.
  1101.  */
  1102.     static char_u *
  1103. cat_prefix_varname(prefix, name)
  1104.     int        prefix;
  1105.     char_u    *name;
  1106. {
  1107.     int        len;
  1108.  
  1109.     len = (int)STRLEN(name) + 3;
  1110.     if (len > varnamebuflen)
  1111.     {
  1112.     vim_free(varnamebuf);
  1113.     len += 10;            /* some additional space */
  1114.     varnamebuf = alloc(len);
  1115.     if (varnamebuf == NULL)
  1116.     {
  1117.         varnamebuflen = 0;
  1118.         return NULL;
  1119.     }
  1120.     varnamebuflen = len;
  1121.     }
  1122.     *varnamebuf = prefix;
  1123.     varnamebuf[1] = ':';
  1124.     STRCPY(varnamebuf + 2, name);
  1125.     return varnamebuf;
  1126. }
  1127.  
  1128. /*
  1129.  * Function given to ExpandGeneric() to obtain the list of user defined
  1130.  * (global/buffer/window/built-in) variable names.
  1131.  */
  1132. /*ARGSUSED*/
  1133.     char_u *
  1134. get_user_var_name(xp, idx)
  1135.     expand_T    *xp;
  1136.     int        idx;
  1137. {
  1138.     static int    gidx;
  1139.     static int    bidx;
  1140.     static int    widx;
  1141.     static int    vidx;
  1142.     char_u    *name;
  1143.  
  1144.     if (idx == 0)
  1145.     gidx = bidx = widx = vidx = 0;
  1146.     if (gidx < variables.ga_len)            /* Global variables */
  1147.     {
  1148.     while ((name = VAR_ENTRY(gidx++).var_name) == NULL
  1149.         && gidx < variables.ga_len)
  1150.         /* skip */;
  1151.     if (name != NULL)
  1152.         return name;
  1153.     }
  1154.     if (bidx < curbuf->b_vars.ga_len)        /* Current buffer variables */
  1155.     {
  1156.     while ((name = BVAR_ENTRY(bidx++).var_name) == NULL
  1157.         && bidx < curbuf->b_vars.ga_len)
  1158.         /* skip */;
  1159.     if (name != NULL)
  1160.         return cat_prefix_varname('b', name);
  1161.     }
  1162.     if (bidx == curbuf->b_vars.ga_len)
  1163.     {
  1164.     ++bidx;
  1165.     return (char_u *)"b:changedtick";
  1166.     }
  1167.     if (widx < curwin->w_vars.ga_len)        /* Current window variables */
  1168.     {
  1169.     while ((name = WVAR_ENTRY(widx++).var_name) == NULL
  1170.         && widx < curwin->w_vars.ga_len)
  1171.         /* skip */;
  1172.     if (name != NULL)
  1173.         return cat_prefix_varname('w', name);
  1174.     }
  1175.     if (vidx < VV_LEN)                      /* Built-in variables */
  1176.     return cat_prefix_varname('v', (char_u *)vimvars[vidx++].name);
  1177.  
  1178.     vim_free(varnamebuf);
  1179.     varnamebuf = NULL;
  1180.     varnamebuflen = 0;
  1181.     return NULL;
  1182. }
  1183.  
  1184. #endif /* FEAT_CMDL_COMPL */
  1185.  
  1186. /*
  1187.  * types for expressions.
  1188.  */
  1189. typedef enum
  1190. {
  1191.     TYPE_UNKNOWN = 0
  1192.     , TYPE_EQUAL    /* == */
  1193.     , TYPE_NEQUAL    /* != */
  1194.     , TYPE_GREATER    /* >  */
  1195.     , TYPE_GEQUAL    /* >= */
  1196.     , TYPE_SMALLER    /* <  */
  1197.     , TYPE_SEQUAL    /* <= */
  1198.     , TYPE_MATCH    /* =~ */
  1199.     , TYPE_NOMATCH    /* !~ */
  1200. } exptype_T;
  1201.  
  1202. /*
  1203.  * The "evaluate" argument: When FALSE, the argument is only parsed but not
  1204.  * executed.  The function may return OK, but the retvar will be of type
  1205.  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
  1206.  */
  1207.  
  1208. /*
  1209.  * Handle zero level expression.
  1210.  * This calls eval1() and handles error message and nextcmd.
  1211.  * Return OK or FAIL.
  1212.  */
  1213.     static int
  1214. eval0(arg, retvar, nextcmd, evaluate)
  1215.     char_u    *arg;
  1216.     VAR        retvar;
  1217.     char_u    **nextcmd;
  1218.     int        evaluate;
  1219. {
  1220.     int        ret;
  1221.     char_u    *p;
  1222.  
  1223.     p = skipwhite(arg);
  1224.     ret = eval1(&p, retvar, evaluate);
  1225.     if (ret == FAIL || !ends_excmd(*p))
  1226.     {
  1227.     if (ret != FAIL)
  1228.         clear_var(retvar);
  1229.     EMSG2(_(e_invexpr2), arg);
  1230.     ret = FAIL;
  1231.     }
  1232.     if (nextcmd != NULL)
  1233.     *nextcmd = check_nextcmd(p);
  1234.  
  1235.     return ret;
  1236. }
  1237.  
  1238. /*
  1239.  * Handle top level expression:
  1240.  *    expr1 ? expr0 : expr0
  1241.  *
  1242.  * "arg" must point to the first non-white of the expression.
  1243.  * "arg" is advanced to the next non-white after the recognized expression.
  1244.  *
  1245.  * Return OK or FAIL.
  1246.  */
  1247.     static int
  1248. eval1(arg, retvar, evaluate)
  1249.     char_u    **arg;
  1250.     VAR        retvar;
  1251.     int        evaluate;
  1252. {
  1253.     int        result;
  1254.     var        var2;
  1255.  
  1256.     /*
  1257.      * Get the first variable.
  1258.      */
  1259.     if (eval2(arg, retvar, evaluate) == FAIL)
  1260.     return FAIL;
  1261.  
  1262.     if ((*arg)[0] == '?')
  1263.     {
  1264.     result = FALSE;
  1265.     if (evaluate)
  1266.     {
  1267.         if (get_var_number(retvar) != 0)
  1268.         result = TRUE;
  1269.         clear_var(retvar);
  1270.     }
  1271.  
  1272.     /*
  1273.      * Get the second variable.
  1274.      */
  1275.     *arg = skipwhite(*arg + 1);
  1276.     if (eval1(arg, retvar, evaluate && result) == FAIL) /* recursive! */
  1277.         return FAIL;
  1278.  
  1279.     /*
  1280.      * Check for the ":".
  1281.      */
  1282.     if ((*arg)[0] != ':')
  1283.     {
  1284.         EMSG(_("E109: Missing ':' after '?'"));
  1285.         return FAIL;
  1286.     }
  1287.  
  1288.     /*
  1289.      * Get the third variable.
  1290.      */
  1291.     *arg = skipwhite(*arg + 1);
  1292.     if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
  1293.         return FAIL;
  1294.     if (evaluate && !result)
  1295.         *retvar = var2;
  1296.     }
  1297.  
  1298.     return OK;
  1299. }
  1300.  
  1301. /*
  1302.  * Handle first level expression:
  1303.  *    expr2 || expr2 || expr2        logical OR
  1304.  *
  1305.  * "arg" must point to the first non-white of the expression.
  1306.  * "arg" is advanced to the next non-white after the recognized expression.
  1307.  *
  1308.  * Return OK or FAIL.
  1309.  */
  1310.     static int
  1311. eval2(arg, retvar, evaluate)
  1312.     char_u    **arg;
  1313.     VAR        retvar;
  1314.     int        evaluate;
  1315. {
  1316.     var        var2;
  1317.     long    result;
  1318.     int        first;
  1319.  
  1320.     /*
  1321.      * Get the first variable.
  1322.      */
  1323.     if (eval3(arg, retvar, evaluate) == FAIL)
  1324.     return FAIL;
  1325.  
  1326.     /*
  1327.      * Repeat until there is no following "||".
  1328.      */
  1329.     while ((*arg)[0] == '|' && (*arg)[1] == '|')
  1330.     {
  1331.     result = FALSE;
  1332.     first = TRUE;
  1333.     if (evaluate && first)
  1334.     {
  1335.         if (get_var_number(retvar) != 0)
  1336.         result = TRUE;
  1337.         clear_var(retvar);
  1338.         first = FALSE;
  1339.     }
  1340.  
  1341.     /*
  1342.      * Get the second variable.
  1343.      */
  1344.     *arg = skipwhite(*arg + 2);
  1345.     if (eval3(arg, &var2, evaluate && !result) == FAIL)
  1346.         return FAIL;
  1347.  
  1348.     /*
  1349.      * Compute the result.
  1350.      */
  1351.     if (evaluate && !result)
  1352.     {
  1353.         if (get_var_number(&var2) != 0)
  1354.         result = TRUE;
  1355.         clear_var(&var2);
  1356.     }
  1357.     if (evaluate)
  1358.     {
  1359.         retvar->var_type = VAR_NUMBER;
  1360.         retvar->var_val.var_number = result;
  1361.     }
  1362.     }
  1363.  
  1364.     return OK;
  1365. }
  1366.  
  1367. /*
  1368.  * Handle second level expression:
  1369.  *    expr3 && expr3 && expr3        logical AND
  1370.  *
  1371.  * "arg" must point to the first non-white of the expression.
  1372.  * "arg" is advanced to the next non-white after the recognized expression.
  1373.  *
  1374.  * Return OK or FAIL.
  1375.  */
  1376.     static int
  1377. eval3(arg, retvar, evaluate)
  1378.     char_u    **arg;
  1379.     VAR        retvar;
  1380.     int        evaluate;
  1381. {
  1382.     var        var2;
  1383.     long    result;
  1384.     int        first;
  1385.  
  1386.     /*
  1387.      * Get the first variable.
  1388.      */
  1389.     if (eval4(arg, retvar, evaluate) == FAIL)
  1390.     return FAIL;
  1391.  
  1392.     /*
  1393.      * Repeat until there is no following "&&".
  1394.      */
  1395.     while ((*arg)[0] == '&' && (*arg)[1] == '&')
  1396.     {
  1397.     result = TRUE;
  1398.     first = TRUE;
  1399.     if (evaluate && first)
  1400.     {
  1401.         if (get_var_number(retvar) == 0)
  1402.         result = FALSE;
  1403.         clear_var(retvar);
  1404.         first = FALSE;
  1405.     }
  1406.  
  1407.     /*
  1408.      * Get the second variable.
  1409.      */
  1410.     *arg = skipwhite(*arg + 2);
  1411.     if (eval4(arg, &var2, evaluate && result) == FAIL)
  1412.         return FAIL;
  1413.  
  1414.     /*
  1415.      * Compute the result.
  1416.      */
  1417.     if (evaluate && result)
  1418.     {
  1419.         if (get_var_number(&var2) == 0)
  1420.         result = FALSE;
  1421.         clear_var(&var2);
  1422.     }
  1423.     if (evaluate)
  1424.     {
  1425.         retvar->var_type = VAR_NUMBER;
  1426.         retvar->var_val.var_number = result;
  1427.     }
  1428.     }
  1429.  
  1430.     return OK;
  1431. }
  1432.  
  1433. /*
  1434.  * Handle third level expression:
  1435.  *    var1 == var2
  1436.  *    var1 =~ var2
  1437.  *    var1 != var2
  1438.  *    var1 !~ var2
  1439.  *    var1 > var2
  1440.  *    var1 >= var2
  1441.  *    var1 < var2
  1442.  *    var1 <= var2
  1443.  *
  1444.  * "arg" must point to the first non-white of the expression.
  1445.  * "arg" is advanced to the next non-white after the recognized expression.
  1446.  *
  1447.  * Return OK or FAIL.
  1448.  */
  1449.     static int
  1450. eval4(arg, retvar, evaluate)
  1451.     char_u    **arg;
  1452.     VAR        retvar;
  1453.     int        evaluate;
  1454. {
  1455.     var        var2;
  1456.     char_u    *p;
  1457.     int        i;
  1458.     exptype_T    type = TYPE_UNKNOWN;
  1459.     int        len = 2;
  1460.     long    n1, n2;
  1461.     char_u    *s1, *s2;
  1462.     char_u    buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  1463.     regmatch_T    regmatch;
  1464.     int        ic;
  1465.     char_u    *save_cpo;
  1466.  
  1467.     /*
  1468.      * Get the first variable.
  1469.      */
  1470.     if (eval5(arg, retvar, evaluate) == FAIL)
  1471.     return FAIL;
  1472.  
  1473.     p = *arg;
  1474.     switch (p[0])
  1475.     {
  1476.     case '=':   if (p[1] == '=')
  1477.             type = TYPE_EQUAL;
  1478.             else if (p[1] == '~')
  1479.             type = TYPE_MATCH;
  1480.             break;
  1481.     case '!':   if (p[1] == '=')
  1482.             type = TYPE_NEQUAL;
  1483.             else if (p[1] == '~')
  1484.             type = TYPE_NOMATCH;
  1485.             break;
  1486.     case '>':   if (p[1] != '=')
  1487.             {
  1488.             type = TYPE_GREATER;
  1489.             len = 1;
  1490.             }
  1491.             else
  1492.             type = TYPE_GEQUAL;
  1493.             break;
  1494.     case '<':   if (p[1] != '=')
  1495.             {
  1496.             type = TYPE_SMALLER;
  1497.             len = 1;
  1498.             }
  1499.             else
  1500.             type = TYPE_SEQUAL;
  1501.             break;
  1502.     }
  1503.  
  1504.     /*
  1505.      * If there is a comparitive operator, use it.
  1506.      */
  1507.     if (type != TYPE_UNKNOWN)
  1508.     {
  1509.     /* extra question mark appended: ignore case */
  1510.     if (p[len] == '?')
  1511.     {
  1512.         ic = TRUE;
  1513.         ++len;
  1514.     }
  1515.     /* extra '#' appended: match case */
  1516.     else if (p[len] == '#')
  1517.     {
  1518.         ic = FALSE;
  1519.         ++len;
  1520.     }
  1521.     /* nothing appened: use 'ignorecase' */
  1522.     else
  1523.         ic = p_ic;
  1524.  
  1525.     /*
  1526.      * Get the second variable.
  1527.      */
  1528.     *arg = skipwhite(p + len);
  1529.     if (eval5(arg, &var2, evaluate) == FAIL)
  1530.     {
  1531.         clear_var(retvar);
  1532.         return FAIL;
  1533.     }
  1534.  
  1535.     if (evaluate)
  1536.     {
  1537.         /*
  1538.          * If one of the two variables is a number, compare as a number.
  1539.          * When using "=~" or "!~", always compare as string.
  1540.          */
  1541.         if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER)
  1542.             && type != TYPE_MATCH && type != TYPE_NOMATCH)
  1543.         {
  1544.         n1 = get_var_number(retvar);
  1545.         n2 = get_var_number(&var2);
  1546.         switch (type)
  1547.         {
  1548.             case TYPE_EQUAL:    n1 = (n1 == n2); break;
  1549.             case TYPE_NEQUAL:   n1 = (n1 != n2); break;
  1550.             case TYPE_GREATER:  n1 = (n1 > n2); break;
  1551.             case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
  1552.             case TYPE_SMALLER:  n1 = (n1 < n2); break;
  1553.             case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
  1554.             case TYPE_UNKNOWN:
  1555.             case TYPE_MATCH:
  1556.             case TYPE_NOMATCH:  break;  /* avoid gcc warning */
  1557.         }
  1558.         }
  1559.         else
  1560.         {
  1561.         s1 = get_var_string_buf(retvar, buf1);
  1562.         s2 = get_var_string_buf(&var2, buf2);
  1563.         if (type != TYPE_MATCH && type != TYPE_NOMATCH)
  1564.             i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
  1565.         else
  1566.             i = 0;
  1567.         n1 = FALSE;
  1568.         switch (type)
  1569.         {
  1570.             case TYPE_EQUAL:    n1 = (i == 0); break;
  1571.             case TYPE_NEQUAL:   n1 = (i != 0); break;
  1572.             case TYPE_GREATER:  n1 = (i > 0); break;
  1573.             case TYPE_GEQUAL:   n1 = (i >= 0); break;
  1574.             case TYPE_SMALLER:  n1 = (i < 0); break;
  1575.             case TYPE_SEQUAL:   n1 = (i <= 0); break;
  1576.  
  1577.             case TYPE_MATCH:
  1578.             case TYPE_NOMATCH:
  1579.                 /* avoid 'l' flag in 'cpoptions' */
  1580.                 save_cpo = p_cpo;
  1581.                 p_cpo = (char_u *)"";
  1582.                 regmatch.regprog = vim_regcomp(s2, TRUE);
  1583.                 regmatch.rm_ic = ic;
  1584.                 if (regmatch.regprog != NULL)
  1585.                 {
  1586.                 n1 = vim_regexec(®match, s1, (colnr_T)0);
  1587.                 vim_free(regmatch.regprog);
  1588.                 if (type == TYPE_NOMATCH)
  1589.                     n1 = !n1;
  1590.                 }
  1591.                 p_cpo = save_cpo;
  1592.                 break;
  1593.  
  1594.             case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
  1595.         }
  1596.         }
  1597.         clear_var(retvar);
  1598.         clear_var(&var2);
  1599.         retvar->var_type = VAR_NUMBER;
  1600.         retvar->var_val.var_number = n1;
  1601.     }
  1602.     }
  1603.  
  1604.     return OK;
  1605. }
  1606.  
  1607. /*
  1608.  * Handle fourth level expression:
  1609.  *    +    number addition
  1610.  *    -    number subtraction
  1611.  *    .    string concatenation
  1612.  *
  1613.  * "arg" must point to the first non-white of the expression.
  1614.  * "arg" is advanced to the next non-white after the recognized expression.
  1615.  *
  1616.  * Return OK or FAIL.
  1617.  */
  1618.     static int
  1619. eval5(arg, retvar, evaluate)
  1620.     char_u    **arg;
  1621.     VAR        retvar;
  1622.     int        evaluate;
  1623. {
  1624.     var        var2;
  1625.     int        op;
  1626.     long    n1, n2;
  1627.     char_u    *s1, *s2;
  1628.     char_u    buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  1629.     char_u    *p;
  1630.  
  1631.     /*
  1632.      * Get the first variable.
  1633.      */
  1634.     if (eval6(arg, retvar, evaluate) == FAIL)
  1635.     return FAIL;
  1636.  
  1637.     /*
  1638.      * Repeat computing, until no '+', '-' or '.' is following.
  1639.      */
  1640.     for (;;)
  1641.     {
  1642.     op = **arg;
  1643.     if (op != '+' && op != '-' && op != '.')
  1644.         break;
  1645.  
  1646.     /*
  1647.      * Get the second variable.
  1648.      */
  1649.     *arg = skipwhite(*arg + 1);
  1650.     if (eval6(arg, &var2, evaluate) == FAIL)
  1651.     {
  1652.         clear_var(retvar);
  1653.         return FAIL;
  1654.     }
  1655.  
  1656.     if (evaluate)
  1657.     {
  1658.         /*
  1659.          * Compute the result.
  1660.          */
  1661.         if (op == '.')
  1662.         {
  1663.         s1 = get_var_string_buf(retvar, buf1);
  1664.         s2 = get_var_string_buf(&var2, buf2);
  1665.         op = (int)STRLEN(s1);
  1666.         p = alloc((unsigned)(op + STRLEN(s2) + 1));
  1667.         if (p != NULL)
  1668.         {
  1669.             STRCPY(p, s1);
  1670.             STRCPY(p + op, s2);
  1671.         }
  1672.         clear_var(retvar);
  1673.         retvar->var_type = VAR_STRING;
  1674.         retvar->var_val.var_string = p;
  1675.         }
  1676.         else
  1677.         {
  1678.         n1 = get_var_number(retvar);
  1679.         n2 = get_var_number(&var2);
  1680.         clear_var(retvar);
  1681.         if (op == '+')
  1682.             n1 = n1 + n2;
  1683.         else
  1684.             n1 = n1 - n2;
  1685.         retvar->var_type = VAR_NUMBER;
  1686.         retvar->var_val.var_number = n1;
  1687.         }
  1688.         clear_var(&var2);
  1689.     }
  1690.     }
  1691.     return OK;
  1692. }
  1693.  
  1694. /*
  1695.  * Handle fifth level expression:
  1696.  *    *    number multiplication
  1697.  *    /    number division
  1698.  *    %    number modulo
  1699.  *
  1700.  * "arg" must point to the first non-white of the expression.
  1701.  * "arg" is advanced to the next non-white after the recognized expression.
  1702.  *
  1703.  * Return OK or FAIL.
  1704.  */
  1705.     static int
  1706. eval6(arg, retvar, evaluate)
  1707.     char_u    **arg;
  1708.     VAR        retvar;
  1709.     int        evaluate;
  1710. {
  1711.     var        var2;
  1712.     int        op;
  1713.     long    n1, n2;
  1714.  
  1715.     /*
  1716.      * Get the first variable.
  1717.      */
  1718.     if (eval7(arg, retvar, evaluate) == FAIL)
  1719.     return FAIL;
  1720.  
  1721.     /*
  1722.      * Repeat computing, until no '*', '/' or '%' is following.
  1723.      */
  1724.     for (;;)
  1725.     {
  1726.     op = **arg;
  1727.     if (op != '*' && op != '/' && op != '%')
  1728.         break;
  1729.  
  1730.     if (evaluate)
  1731.     {
  1732.         n1 = get_var_number(retvar);
  1733.         clear_var(retvar);
  1734.     }
  1735.     else
  1736.         n1 = 0;
  1737.  
  1738.     /*
  1739.      * Get the second variable.
  1740.      */
  1741.     *arg = skipwhite(*arg + 1);
  1742.     if (eval7(arg, &var2, evaluate) == FAIL)
  1743.         return FAIL;
  1744.  
  1745.     if (evaluate)
  1746.     {
  1747.         n2 = get_var_number(&var2);
  1748.         clear_var(&var2);
  1749.  
  1750.         /*
  1751.          * Compute the result.
  1752.          */
  1753.         if (op == '*')
  1754.         n1 = n1 * n2;
  1755.         else if (op == '/')
  1756.         {
  1757.         if (n2 == 0)    /* give an error message? */
  1758.             n1 = 0x7fffffffL;
  1759.         else
  1760.             n1 = n1 / n2;
  1761.         }
  1762.         else
  1763.         {
  1764.         if (n2 == 0)    /* give an error message? */
  1765.             n1 = 0;
  1766.         else
  1767.             n1 = n1 % n2;
  1768.         }
  1769.         retvar->var_type = VAR_NUMBER;
  1770.         retvar->var_val.var_number = n1;
  1771.     }
  1772.     }
  1773.  
  1774.     return OK;
  1775. }
  1776.  
  1777. /*
  1778.  * Handle sixth level expression:
  1779.  *  number        number constant
  1780.  *  "string"        string contstant
  1781.  *  *option-name    option value
  1782.  *  @r            register contents
  1783.  *  identifier        variable value
  1784.  *  funcion()        function call
  1785.  *  $VAR        environment variable
  1786.  *  (expression)    nested expression
  1787.  *
  1788.  *  Also handle:
  1789.  *  ! in front        logical NOT
  1790.  *  - in front        unary minus
  1791.  *  + in front        unary plus (ignored)
  1792.  *  trailing []        subscript in String
  1793.  *
  1794.  * "arg" must point to the first non-white of the expression.
  1795.  * "arg" is advanced to the next non-white after the recognized expression.
  1796.  *
  1797.  * Return OK or FAIL.
  1798.  */
  1799.     static int
  1800. eval7(arg, retvar, evaluate)
  1801.     char_u    **arg;
  1802.     VAR        retvar;
  1803.     int        evaluate;
  1804. {
  1805.     var        var2;
  1806.     long    n;
  1807.     int        len;
  1808.     char_u    *s;
  1809.     int        val;
  1810.     char_u    *start_leader, *end_leader;
  1811.     int        ret = OK;
  1812.     char_u    *alias;
  1813.  
  1814.     /*
  1815.      * Initialise variable so that clear_var() can't mistake this for a string
  1816.      * and free a string that isn't there.
  1817.      */
  1818.     retvar->var_type = VAR_UNKNOWN;
  1819.  
  1820.     /*
  1821.      * Skip '!' and '-' characters.  They are handled later.
  1822.      */
  1823.     start_leader = *arg;
  1824.     while (**arg == '!' || **arg == '-' || **arg == '+')
  1825.     *arg = skipwhite(*arg + 1);
  1826.     end_leader = *arg;
  1827.  
  1828.     switch (**arg)
  1829.     {
  1830.     /*
  1831.      * Number constant.
  1832.      */
  1833.     case '0':
  1834.     case '1':
  1835.     case '2':
  1836.     case '3':
  1837.     case '4':
  1838.     case '5':
  1839.     case '6':
  1840.     case '7':
  1841.     case '8':
  1842.     case '9':
  1843.         vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
  1844.         *arg += len;
  1845.         if (evaluate)
  1846.         {
  1847.             retvar->var_type = VAR_NUMBER;
  1848.             retvar->var_val.var_number = n;
  1849.         }
  1850.         break;
  1851.  
  1852.     /*
  1853.      * String constant: "string".
  1854.      */
  1855.     case '"':    ret = get_string_var(arg, retvar, evaluate);
  1856.         break;
  1857.  
  1858.     /*
  1859.      * Literal string constant: 'string'.
  1860.      */
  1861.     case '\'':    ret = get_lit_string_var(arg, retvar, evaluate);
  1862.         break;
  1863.  
  1864.     /*
  1865.      * Option value: &name
  1866.      */
  1867.     case '&':    ret = get_option_var(arg, retvar, evaluate);
  1868.         break;
  1869.  
  1870.     /*
  1871.      * Environment variable: $VAR.
  1872.      */
  1873.     case '$':    ret = get_env_var(arg, retvar, evaluate);
  1874.         break;
  1875.  
  1876.     /*
  1877.      * Register contents: @r.
  1878.      */
  1879.     case '@':    ++*arg;
  1880.         if (evaluate)
  1881.         {
  1882.             retvar->var_type = VAR_STRING;
  1883.             retvar->var_val.var_string = get_reg_contents(**arg);
  1884.         }
  1885.         if (**arg != NUL)
  1886.             ++*arg;
  1887.         break;
  1888.  
  1889.     /*
  1890.      * nested expression: (expression).
  1891.      */
  1892.     case '(':    *arg = skipwhite(*arg + 1);
  1893.         ret = eval1(arg, retvar, evaluate);    /* recursive! */
  1894.         if (**arg == ')')
  1895.             ++*arg;
  1896.         else if (ret == OK)
  1897.         {
  1898.             EMSG(_("E110: Missing ')'"));
  1899.             ret = FAIL;
  1900.         }
  1901.         break;
  1902.  
  1903.     /*
  1904.      * Must be a variable or function name then.
  1905.      */
  1906.     default:    s = *arg;
  1907.         len = get_func_len(arg, &alias);
  1908.         if (alias != NULL)
  1909.             s = alias;
  1910.  
  1911.         if (len != 0)
  1912.         {
  1913.             if (**arg == '(')        /* recursive! */
  1914.             ret = get_func_var(s, len, retvar, arg,
  1915.                   curwin->w_cursor.lnum, curwin->w_cursor.lnum,
  1916.                   &len, evaluate);
  1917.             else if (evaluate)
  1918.             ret = get_var_var(s, len, retvar);
  1919.         }
  1920.         else
  1921.             ret = FAIL;
  1922.  
  1923.         if (alias != NULL)
  1924.             vim_free(alias);
  1925.  
  1926.         break;
  1927.     }
  1928.     *arg = skipwhite(*arg);
  1929.  
  1930.     /*
  1931.      * Handle expr[expr] subscript.
  1932.      */
  1933.     if (**arg == '[' && ret == OK)
  1934.     {
  1935.     /*
  1936.      * Get the variable from inside the [].
  1937.      */
  1938.     *arg = skipwhite(*arg + 1);
  1939.     if (eval1(arg, &var2, evaluate) == FAIL)    /* recursive! */
  1940.     {
  1941.         clear_var(retvar);
  1942.         return FAIL;
  1943.     }
  1944.  
  1945.     /* Check for the ']'. */
  1946.     if (**arg != ']')
  1947.     {
  1948.         EMSG(_("E111: Missing ']'"));
  1949.         clear_var(retvar);
  1950.         return FAIL;
  1951.     }
  1952.  
  1953.     if (evaluate)
  1954.     {
  1955.         n = get_var_number(&var2);
  1956.         clear_var(&var2);
  1957.  
  1958.         /*
  1959.          * The resulting variable is a string of a single character.
  1960.          * If the index is too big or negative, the result is empty.
  1961.          */
  1962.         s = get_var_string(retvar);
  1963.         if (n >= (long)STRLEN(s) || n < 0)
  1964.         s = NULL;
  1965.         else
  1966.         s = vim_strnsave(s + n, 1);
  1967.         clear_var(retvar);
  1968.         retvar->var_type = VAR_STRING;
  1969.         retvar->var_val.var_string = s;
  1970.     }
  1971.     *arg = skipwhite(*arg + 1);    /* skip the ']' */
  1972.     }
  1973.  
  1974.     /*
  1975.      * Apply logical NOT and unary '-', from right to left, ignore '+'.
  1976.      */
  1977.     if (ret == OK && evaluate && end_leader > start_leader)
  1978.     {
  1979.     val = get_var_number(retvar);
  1980.     while (end_leader > start_leader)
  1981.     {
  1982.         --end_leader;
  1983.         if (*end_leader == '!')
  1984.         val = !val;
  1985.         else if (*end_leader == '-')
  1986.         val = -val;
  1987.     }
  1988.     clear_var(retvar);
  1989.     retvar->var_type = VAR_NUMBER;
  1990.     retvar->var_val.var_number = val;
  1991.     }
  1992.  
  1993.     return ret;
  1994. }
  1995.  
  1996. /*
  1997.  * Get an option value.
  1998.  * "arg" points to the '&' before the option name.
  1999.  * "arg" is advanced to character after the option name.
  2000.  * Return OK or FAIL.
  2001.  */
  2002.     static int
  2003. get_option_var(arg, retvar, evaluate)
  2004.     char_u    **arg;
  2005.     VAR        retvar;        /* when NULL, only check if option exists */
  2006.     int        evaluate;
  2007. {
  2008.     char_u    *option_end;
  2009.     long    numval;
  2010.     char_u    *stringval;
  2011.     int        opt_type;
  2012.     int        c;
  2013.     int        ret = OK;
  2014.     int        opt_flags;
  2015.  
  2016.     /*
  2017.      * Isolate the option name and find its value.
  2018.      */
  2019.     option_end = find_option_end(arg, &opt_flags);
  2020.     if (option_end == NULL)
  2021.     {
  2022.     if (retvar != NULL)
  2023.         EMSG2(_("E112: Option name missing: %s"), *arg);
  2024.     return FAIL;
  2025.     }
  2026.  
  2027.     if (!evaluate)
  2028.     {
  2029.     *arg = option_end;
  2030.     return OK;
  2031.     }
  2032.  
  2033.     c = *option_end;
  2034.     *option_end = NUL;
  2035.     opt_type = get_option_value(*arg, &numval,
  2036.                    retvar == NULL ? NULL : &stringval, 0);
  2037.  
  2038.     if (opt_type == -3)            /* invalid name */
  2039.     {
  2040.     if (retvar != NULL)
  2041.         EMSG2(_("E113: Unknown option: %s"), *arg);
  2042.     ret = FAIL;
  2043.     }
  2044.     else if (retvar != NULL)
  2045.     {
  2046.     if (opt_type == -2)        /* hidden string option */
  2047.     {
  2048.         retvar->var_type = VAR_STRING;
  2049.         retvar->var_val.var_string = NULL;
  2050.     }
  2051.     else if (opt_type == -1)    /* hidden number option */
  2052.     {
  2053.         retvar->var_type = VAR_NUMBER;
  2054.         retvar->var_val.var_number = 0;
  2055.     }
  2056.     else if (opt_type == 1)        /* number option */
  2057.     {
  2058.         retvar->var_type = VAR_NUMBER;
  2059.         retvar->var_val.var_number = numval;
  2060.     }
  2061.     else                /* string option */
  2062.     {
  2063.         retvar->var_type = VAR_STRING;
  2064.         retvar->var_val.var_string = stringval;
  2065.     }
  2066.     }
  2067.  
  2068.     *option_end = c;            /* put back for error messages */
  2069.     *arg = option_end;
  2070.  
  2071.     return ret;
  2072. }
  2073.  
  2074. /*
  2075.  * Allocate a variable for an string constant.
  2076.  * Return OK or FAIL.
  2077.  */
  2078.     static int
  2079. get_string_var(arg, retvar, evaluate)
  2080.     char_u    **arg;
  2081.     VAR        retvar;
  2082.     int        evaluate;
  2083. {
  2084.     char_u    *p;
  2085.     char_u    *name;
  2086.     int        i;
  2087.     int        extra = 0;
  2088.  
  2089.     /*
  2090.      * Find the end of the string, skipping backslashed characters.
  2091.      */
  2092.     for (p = *arg + 1; *p && *p != '"'; ++p)
  2093.     if (*p == '\\' && p[1] != NUL)
  2094.     {
  2095.         ++p;
  2096.         /* A "\<x>" form occupies at least 4 characters, and produces up
  2097.          * to 6 characters: reserve space for 2 extra */
  2098.         if (*p == '<')
  2099.         extra += 2;
  2100.     }
  2101.     if (*p != '"')
  2102.     {
  2103.     EMSG2(_("E114: Missing quote: %s"), *arg);
  2104.     return FAIL;
  2105.     }
  2106.  
  2107.     /* If only parsing, set *arg and return here */
  2108.     if (!evaluate)
  2109.     {
  2110.     *arg = p + 1;
  2111.     return OK;
  2112.     }
  2113.  
  2114.     /*
  2115.      * Copy the string into allocated memory, handling backslashed
  2116.      * characters.
  2117.      */
  2118.     name = alloc((unsigned)(p - *arg + extra));
  2119.     if (name == NULL)
  2120.     return FAIL;
  2121.  
  2122.     i = 0;
  2123.     for (p = *arg + 1; *p && *p != '"'; ++p)
  2124.     {
  2125.     if (*p == '\\')
  2126.     {
  2127.         switch (*++p)
  2128.         {
  2129.         case 'b': name[i++] = BS; break;
  2130.         case 'e': name[i++] = ESC; break;
  2131.         case 'f': name[i++] = FF; break;
  2132.         case 'n': name[i++] = NL; break;
  2133.         case 'r': name[i++] = CR; break;
  2134.         case 't': name[i++] = TAB; break;
  2135.  
  2136.               /* hex: "\x1", "\x12" */
  2137.         case 'X':
  2138.         case 'x': if (isxdigit(p[1]))
  2139.               {
  2140.                   ++p;
  2141.                   name[i] = hex2nr(*p);
  2142.                   if (isxdigit(p[1]))
  2143.                   {
  2144.                   ++p;
  2145.                   name[i] = (name[i] << 4) + hex2nr(*p);
  2146.                   }
  2147.                   ++i;
  2148.               }
  2149.               else
  2150.                   name[i++] = *p;
  2151.               break;
  2152.  
  2153.               /* octal: "\1", "\12", "\123" */
  2154.         case '0':
  2155.         case '1':
  2156.         case '2':
  2157.         case '3':
  2158.         case '4':
  2159.         case '5':
  2160.         case '6':
  2161.         case '7': name[i] = *p - '0';
  2162.               if (p[1] >= '0' && p[1] <= '7')
  2163.               {
  2164.                   ++p;
  2165.                   name[i] = (name[i] << 3) + *p - '0';
  2166.                   if (p[1] >= '0' && p[1] <= '7')
  2167.                   {
  2168.                   ++p;
  2169.                   name[i] = (name[i] << 3) + *p - '0';
  2170.                   }
  2171.               }
  2172.               ++i;
  2173.               break;
  2174.  
  2175.                 /* Special key, e.g.: "\<C-W>" */
  2176.         case '<': extra = trans_special(&p, name + i, TRUE);
  2177.               if (extra != 0)
  2178.               {
  2179.                   i += extra;
  2180.                   --p;
  2181.                   break;
  2182.               }
  2183.               /* FALLTHROUGH */
  2184.  
  2185.         default:  name[i++] = *p;
  2186.               break;
  2187.         }
  2188.     }
  2189.     else
  2190.         name[i++] = *p;
  2191.     }
  2192.     name[i] = NUL;
  2193.     *arg = p + 1;
  2194.  
  2195.     retvar->var_type = VAR_STRING;
  2196.     retvar->var_val.var_string = name;
  2197.  
  2198.     return OK;
  2199. }
  2200.  
  2201. /*
  2202.  * Allocate a variable for an backtick-string constant.
  2203.  * Return OK or FAIL.
  2204.  */
  2205.     static int
  2206. get_lit_string_var(arg, retvar, evaluate)
  2207.     char_u    **arg;
  2208.     VAR        retvar;
  2209.     int        evaluate;
  2210. {
  2211.     char_u    *p;
  2212.     char_u    *name;
  2213.  
  2214.     /*
  2215.      * Find the end of the string.
  2216.      */
  2217.     p = vim_strchr(*arg + 1, '\'');
  2218.     if (p == NULL)
  2219.     {
  2220.     EMSG2(_("E115: Missing quote: %s"), *arg);
  2221.     return FAIL;
  2222.     }
  2223.  
  2224.     if (evaluate)
  2225.     {
  2226.     /*
  2227.      * Copy the string into allocated memory.
  2228.      */
  2229.     name = vim_strnsave(*arg + 1, (int)(p - (*arg + 1)));
  2230.     if (name == NULL)
  2231.         return FAIL;
  2232.  
  2233.     retvar->var_type = VAR_STRING;
  2234.     retvar->var_val.var_string = name;
  2235.     }
  2236.  
  2237.     *arg = p + 1;
  2238.  
  2239.     return OK;
  2240. }
  2241.  
  2242. /*
  2243.  * Get the value of an environment variable.
  2244.  * "arg" is pointing to the '$'.  It is advanced to after the name.
  2245.  * If the environment variable was not set, silently assume it is empty.
  2246.  * Always return OK.
  2247.  */
  2248.     static int
  2249. get_env_var(arg, retvar, evaluate)
  2250.     char_u    **arg;
  2251.     VAR        retvar;
  2252.     int        evaluate;
  2253. {
  2254.     char_u    *string = NULL;
  2255.     int        len;
  2256.     int        cc;
  2257.     char_u    *name;
  2258.  
  2259.     ++*arg;
  2260.     name = *arg;
  2261.     len = get_env_len(arg);
  2262.     if (evaluate)
  2263.     {
  2264.     if (len != 0)
  2265.     {
  2266.         cc = name[len];
  2267.         name[len] = NUL;
  2268.         /* first try mch_getenv(), fast for normal environment vars */
  2269.         string = mch_getenv(name);
  2270.         if (string != NULL && *string != NUL)
  2271.         string = vim_strsave(string);
  2272.         else
  2273.         {
  2274.         /* next try expanding things like $VIM and ${HOME} */
  2275.         string = expand_env_save(name - 1);
  2276.         if (string != NULL && *string == '$')
  2277.         {
  2278.             vim_free(string);
  2279.             string = NULL;
  2280.         }
  2281.         }
  2282.         name[len] = cc;
  2283.     }
  2284.     retvar->var_type = VAR_STRING;
  2285.     retvar->var_val.var_string = string;
  2286.     }
  2287.  
  2288.     return OK;
  2289. }
  2290.  
  2291. /*
  2292.  * Array with names and number of arguments of all internal functions
  2293.  * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
  2294.  */
  2295. static struct fst
  2296. {
  2297.     char    *f_name;    /* function name */
  2298.     char    f_min_argc;    /* minimal number of arguments */
  2299.     char    f_max_argc;    /* maximal number of arguments */
  2300.     void    (*f_func) __ARGS((VAR args, VAR rvar)); /* impl. function */
  2301. } functions[] =
  2302. {
  2303.     {"append",        2, 2, f_append},
  2304.     {"argc",        0, 0, f_argc},
  2305.     {"argidx",        0, 0, f_argidx},
  2306.     {"argv",        1, 1, f_argv},
  2307.     {"browse",        4, 4, f_browse},
  2308.     {"bufexists",    1, 1, f_bufexists},
  2309.     {"buffer_exists",    1, 1, f_bufexists},    /* obsolete */
  2310.     {"buffer_name",    1, 1, f_bufname},    /* obsolete */
  2311.     {"buffer_number",    1, 1, f_bufnr},        /* obsolete */
  2312.     {"buflisted",    1, 1, f_buflisted},
  2313.     {"bufloaded",    1, 1, f_bufloaded},
  2314.     {"bufname",        1, 1, f_bufname},
  2315.     {"bufnr",        1, 1, f_bufnr},
  2316.     {"bufwinnr",    1, 1, f_bufwinnr},
  2317.     {"byte2line",    1, 1, f_byte2line},
  2318.     {"char2nr",        1, 1, f_char2nr},
  2319.     {"cindent",        1, 1, f_cindent},
  2320.     {"col",        1, 1, f_col},
  2321.     {"confirm",        2, 4, f_confirm},
  2322.     {"cscope_connection",0,3, f_cscope_connection},
  2323.     {"delete",        1, 1, f_delete},
  2324.     {"did_filetype",    0, 0, f_did_filetype},
  2325.     {"escape",        2, 2, f_escape},
  2326.     {"eventhandler",    0, 0, f_eventhandler},
  2327.     {"executable",    1, 1, f_executable},
  2328.     {"exists",        1, 1, f_exists},
  2329.     {"expand",        1, 2, f_expand},
  2330.     {"file_readable",    1, 1, f_filereadable},    /* obsolete */
  2331.     {"filereadable",    1, 1, f_filereadable},
  2332.     {"filewritable",    1, 1, f_filewritable},
  2333.     {"fnamemodify",    2, 2, f_fnamemodify},
  2334.     {"foldclosed",    1, 1, f_foldclosed},
  2335.     {"foldclosedend",    1, 1, f_foldclosedend},
  2336.     {"foldlevel",    1, 1, f_foldlevel},
  2337.     {"foldtext",    0, 0, f_foldtext},
  2338.     {"foreground",    0, 0, f_foreground},
  2339.     {"getbufvar",    2, 2, f_getbufvar},
  2340.     {"getchar",        0, 1, f_getchar},
  2341.     {"getcharmod",    0, 0, f_getcharmod},
  2342.     {"getcwd",        0, 0, f_getcwd},
  2343.     {"getfsize",    1, 1, f_getfsize},
  2344.     {"getftime",    1, 1, f_getftime},
  2345.     {"getline",        1, 1, f_getline},
  2346.     {"getwinposx",    0, 0, f_getwinposx},
  2347.     {"getwinposy",    0, 0, f_getwinposy},
  2348.     {"getwinvar",    2, 2, f_getwinvar},
  2349.     {"glob",        1, 1, f_glob},
  2350.     {"globpath",    2, 2, f_globpath},
  2351.     {"has",        1, 1, f_has},
  2352.     {"hasmapto",    1, 2, f_hasmapto},
  2353.     {"highlightID",    1, 1, f_hlID},        /* obsolete */
  2354.     {"highlight_exists",1, 1, f_hlexists},    /* obsolete */
  2355.     {"histadd",        2, 2, f_histadd},
  2356.     {"histdel",        1, 2, f_histdel},
  2357.     {"histget",        1, 2, f_histget},
  2358.     {"histnr",        1, 1, f_histnr},
  2359.     {"hlID",        1, 1, f_hlID},
  2360.     {"hlexists",    1, 1, f_hlexists},
  2361.     {"hostname",    0, 0, f_hostname},
  2362.     {"iconv",        3, 3, f_iconv},
  2363.     {"indent",        1, 1, f_indent},
  2364.     {"input",        1, 2, f_input},
  2365.     {"inputdialog",    1, 2, f_inputdialog},
  2366.     {"inputsecret",    1, 2, f_inputsecret},
  2367.     {"isdirectory",    1, 1, f_isdirectory},
  2368.     {"last_buffer_nr",    0, 0, f_last_buffer_nr},/* obsolete */
  2369.     {"libcall",        3, 3, f_libcall},
  2370.     {"libcallnr",    3, 3, f_libcallnr},
  2371.     {"line",        1, 1, f_line},
  2372.     {"line2byte",    1, 1, f_line2byte},
  2373.     {"lispindent",    1, 1, f_lispindent},
  2374.     {"localtime",    0, 0, f_localtime},
  2375.     {"maparg",        1, 2, f_maparg},
  2376.     {"mapcheck",    1, 2, f_mapcheck},
  2377.     {"match",        2, 3, f_match},
  2378.     {"matchend",    2, 3, f_matchend},
  2379.     {"matchstr",    2, 3, f_matchstr},
  2380.     {"mode",        0, 0, f_mode},
  2381.     {"nextnonblank",    1, 1, f_nextnonblank},
  2382.     {"nr2char",        1, 1, f_nr2char},
  2383.     {"prevnonblank",    1, 1, f_prevnonblank},
  2384.     {"remote_expr",    2, 3, f_remote_expr},
  2385.     {"remote_foreground", 1, 1, f_remote_foreground},
  2386.     {"remote_peek",    1, 2, f_remote_peek},
  2387.     {"remote_read",    1, 1, f_remote_read},
  2388.     {"remote_send",    2, 3, f_remote_send},
  2389.     {"rename",        2, 2, f_rename},
  2390.     {"resolve",        1, 1, f_resolve},
  2391.     {"search",        1, 2, f_search},
  2392.     {"searchpair",    3, 5, f_searchpair},
  2393.     {"server2client",    2, 2, f_server2client},
  2394.     {"serverlist",    0, 0, f_serverlist},
  2395.     {"setbufvar",    3, 3, f_setbufvar},
  2396.     {"setline",        2, 2, f_setline},
  2397.     {"setwinvar",    3, 3, f_setwinvar},
  2398. #ifdef HAVE_STRFTIME
  2399.     {"strftime",    1, 2, f_strftime},
  2400. #endif
  2401.     {"stridx",        2, 2, f_stridx},
  2402.     {"strlen",        1, 1, f_strlen},
  2403.     {"strpart",        2, 3, f_strpart},
  2404.     {"strridx",        2, 2, f_strridx},
  2405.     {"strtrans",    1, 1, f_strtrans},
  2406.     {"submatch",    1, 1, f_submatch},
  2407.     {"substitute",    4, 4, f_substitute},
  2408.     {"synID",        3, 3, f_synID},
  2409.     {"synIDattr",    2, 3, f_synIDattr},
  2410.     {"synIDtrans",    1, 1, f_synIDtrans},
  2411.     {"system",        1, 1, f_system},
  2412.     {"tempname",    0, 0, f_tempname},
  2413.     {"tolower",        1, 1, f_tolower},
  2414.     {"toupper",        1, 1, f_toupper},
  2415.     {"type",        1, 1, f_type},
  2416.     {"virtcol",        1, 1, f_virtcol},
  2417.     {"visualmode",    0, 0, f_visualmode},
  2418.     {"winbufnr",    1, 1, f_winbufnr},
  2419.     {"wincol",        0, 0, f_wincol},
  2420.     {"winheight",    1, 1, f_winheight},
  2421.     {"winline",        0, 0, f_winline},
  2422.     {"winnr",        0, 0, f_winnr},
  2423.     {"winwidth",    1, 1, f_winwidth},
  2424. };
  2425.  
  2426. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  2427.  
  2428. /*
  2429.  * Function given to ExpandGeneric() to obtain the list of internal
  2430.  * or user defined function names.
  2431.  */
  2432.     char_u *
  2433. get_function_name(xp, idx)
  2434.     expand_T    *xp;
  2435.     int        idx;
  2436. {
  2437.     static int    intidx = -1;
  2438.     char_u    *name;
  2439.  
  2440.     if (idx == 0)
  2441.     intidx = -1;
  2442.     if (intidx < 0)
  2443.     {
  2444.     name = get_user_func_name(xp, idx);
  2445.     if (name != NULL)
  2446.         return name;
  2447.     }
  2448.     if (++intidx < (int)(sizeof(functions) / sizeof(struct fst)))
  2449.     {
  2450.     STRCPY(IObuff, functions[intidx].f_name);
  2451.     STRCAT(IObuff, "(");
  2452.     if (functions[intidx].f_max_argc == 0)
  2453.         STRCAT(IObuff, ")");
  2454.     return IObuff;
  2455.     }
  2456.  
  2457.     return NULL;
  2458. }
  2459.  
  2460. /*
  2461.  * Function given to ExpandGeneric() to obtain the list of internal or
  2462.  * user defined variable or function names.
  2463.  */
  2464. /*ARGSUSED*/
  2465.     char_u *
  2466. get_expr_name(xp, idx)
  2467.     expand_T    *xp;
  2468.     int        idx;
  2469. {
  2470.     static int    intidx = -1;
  2471.     char_u    *name;
  2472.  
  2473.     if (idx == 0)
  2474.     intidx = -1;
  2475.     if (intidx < 0)
  2476.     {
  2477.     name = get_function_name(xp, idx);
  2478.     if (name != NULL)
  2479.         return name;
  2480.     }
  2481.     return get_user_var_name(xp, ++intidx);
  2482. }
  2483.  
  2484. #endif /* FEAT_CMDL_COMPL */
  2485.  
  2486. /*
  2487.  * Find internal function in table above.
  2488.  * Return index, or -1 if not found
  2489.  */
  2490.     static int
  2491. find_internal_func(name)
  2492.     char_u    *name;        /* name of the function */
  2493. {
  2494.     int        first = 0;
  2495.     int        last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
  2496.     int        cmp;
  2497.     int        x;
  2498.  
  2499.     /*
  2500.      * Find the function name in the table. Binary search.
  2501.      */
  2502.     while (first <= last)
  2503.     {
  2504.     x = first + ((unsigned)(last - first) >> 1);
  2505.     cmp = STRCMP(name, functions[x].f_name);
  2506.     if (cmp < 0)
  2507.         last = x - 1;
  2508.     else if (cmp > 0)
  2509.         first = x + 1;
  2510.     else
  2511.         return x;
  2512.     }
  2513.     return -1;
  2514. }
  2515.  
  2516. /*
  2517.  * Allocate a variable for the result of a function.
  2518.  * Return OK or FAIL.
  2519.  */
  2520.     static int
  2521. get_func_var(name, len, retvar, arg, firstline, lastline, doesrange, evaluate)
  2522.     char_u    *name;        /* name of the function */
  2523.     int        len;        /* length of "name" */
  2524.     VAR        retvar;
  2525.     char_u    **arg;        /* argument, pointing to the '(' */
  2526.     linenr_T    firstline;    /* first line of range */
  2527.     linenr_T    lastline;    /* last line of range */
  2528.     int        *doesrange;    /* return: function handled range */
  2529.     int        evaluate;
  2530. {
  2531.     char_u    *argp;
  2532.     int        ret = FAIL;
  2533. #define MAX_FUNC_ARGS    20
  2534.     var        argvars[MAX_FUNC_ARGS];    /* vars for arguments */
  2535.     int        argcount = 0;        /* number of arguments found */
  2536.     static char *errors[] =
  2537.         {N_("E116: Invalid arguments for function %s"),
  2538.          N_("E117: Unknown function: %s"),
  2539.          N_("E118: Too many arguments for function: %s"),
  2540.          N_("E119: Not enough arguments for function: %s"),
  2541.          N_("E120: Using <SID> not in a script context: %s"),
  2542.         };
  2543. #define ERROR_INVARG    0
  2544. #define ERROR_UNKNOWN    1
  2545. #define ERROR_TOOMANY    2
  2546. #define ERROR_TOOFEW    3
  2547. #define ERROR_SCRIPT    4
  2548. #define ERROR_NONE    5
  2549. #define ERROR_OTHER    6
  2550.     int        error = ERROR_NONE;
  2551.     int        i;
  2552.     int        llen;
  2553.     ufunc_T    *fp;
  2554.     int        cc;
  2555. #define FLEN_FIXED 40
  2556.     char_u    fname_buf[FLEN_FIXED + 1];
  2557.     char_u    *fname;
  2558.  
  2559.     /*
  2560.      * In a script change <SID>name() and s:name() to K_SNR 123_name().
  2561.      * Change <SNR>123_name() to K_SNR 123_name().
  2562.      * Use fname_buf[] when it fits, otherwise allocate memory (slow).
  2563.      */
  2564.     cc = name[len];
  2565.     name[len] = NUL;
  2566.     llen = eval_fname_script(name);
  2567.     if (llen > 0)
  2568.     {
  2569.     fname_buf[0] = K_SPECIAL;
  2570.     fname_buf[1] = KS_EXTRA;
  2571.     fname_buf[2] = (int)KE_SNR;
  2572.     i = 3;
  2573.     if (eval_fname_sid(name))    /* "<SID>" or "s:" */
  2574.     {
  2575.         if (current_SID <= 0)
  2576.         error = ERROR_SCRIPT;
  2577.         else
  2578.         {
  2579.         sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
  2580.         i = (int)STRLEN(fname_buf);
  2581.         }
  2582.     }
  2583.     if (i + STRLEN(name + llen) < FLEN_FIXED)
  2584.     {
  2585.         STRCPY(fname_buf + i, name + llen);
  2586.         fname = fname_buf;
  2587.     }
  2588.     else
  2589.     {
  2590.         fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
  2591.         if (fname == NULL)
  2592.         error = ERROR_OTHER;
  2593.         else
  2594.         {
  2595.         mch_memmove(fname, fname_buf, (size_t)i);
  2596.         STRCPY(fname + i, name + llen);
  2597.         }
  2598.     }
  2599.     }
  2600.     else
  2601.     fname = name;
  2602.  
  2603.     *doesrange = FALSE;
  2604.  
  2605.     /*
  2606.      * Get the arguments.
  2607.      */
  2608.     argp = *arg;
  2609.     while (argcount < MAX_FUNC_ARGS)
  2610.     {
  2611.     argp = skipwhite(argp + 1);        /* skip the '(' or ',' */
  2612.     if (*argp == ')' || *argp == ',' || *argp == NUL)
  2613.         break;
  2614.     if (eval1(&argp, &argvars[argcount], evaluate) == FAIL)
  2615.     {
  2616.         error = ERROR_OTHER;
  2617.         break;
  2618.     }
  2619.     ++argcount;
  2620.     if (*argp != ',')
  2621.         break;
  2622.     }
  2623.     if (*argp == ')')
  2624.     ++argp;
  2625.     else if (error == ERROR_NONE)
  2626.     error = ERROR_INVARG;
  2627.  
  2628.     /* execute the function if no errors detected and executing */
  2629.     if (evaluate && error == ERROR_NONE)
  2630.     {
  2631.     retvar->var_type = VAR_NUMBER;    /* default is number retvar */
  2632.     error = ERROR_UNKNOWN;
  2633.  
  2634.     if (!ASCII_ISLOWER(fname[0]))
  2635.     {
  2636.         /*
  2637.          * User defined function.
  2638.          */
  2639.         fp = find_func(fname);
  2640. #ifdef FEAT_AUTOCMD
  2641.         if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED,
  2642.                             fname, fname, TRUE, NULL))
  2643.         {
  2644.         /* executed an autocommand, search for function again */
  2645.         fp = find_func(fname);
  2646.         }
  2647. #endif
  2648.         if (fp != NULL)
  2649.         {
  2650.         if (fp->flags & FC_RANGE)
  2651.             *doesrange = TRUE;
  2652.         if (argcount < fp->args.ga_len)
  2653.             error = ERROR_TOOFEW;
  2654.         else if (!fp->varargs && argcount > fp->args.ga_len)
  2655.             error = ERROR_TOOMANY;
  2656.         else
  2657.         {
  2658.             /*
  2659.              * Call the user function.
  2660.              * Save and restore search patterns, script variables and
  2661.              * redo buffer.
  2662.              */
  2663.             save_search_patterns();
  2664.             saveRedobuff();
  2665.             ++fp->calls;
  2666.             call_func(fp, argcount, argvars, retvar,
  2667.                              firstline, lastline);
  2668.             --fp->calls;
  2669.             restoreRedobuff();
  2670.             restore_search_patterns();
  2671.             error = ERROR_NONE;
  2672.         }
  2673.         }
  2674.     }
  2675.     else
  2676.     {
  2677.         /*
  2678.          * Find the function name in the table, call its implementation.
  2679.          */
  2680.         i = find_internal_func(fname);
  2681.         if (i >= 0)
  2682.         {
  2683.         if (argcount < functions[i].f_min_argc)
  2684.             error = ERROR_TOOFEW;
  2685.         else if (argcount > functions[i].f_max_argc)
  2686.             error = ERROR_TOOMANY;
  2687.         else
  2688.         {
  2689.             argvars[argcount].var_type = VAR_UNKNOWN;
  2690.             functions[i].f_func(argvars, retvar);
  2691.             error = ERROR_NONE;
  2692.         }
  2693.         }
  2694.     }
  2695.     }
  2696.     if (error == ERROR_NONE)
  2697.     ret = OK;
  2698.  
  2699.     *arg = skipwhite(argp);
  2700.  
  2701.     while (--argcount >= 0)
  2702.     clear_var(&argvars[argcount]);
  2703.  
  2704.     if (error < ERROR_NONE)
  2705.     EMSG2((char_u *)_(errors[error]), name);
  2706.  
  2707.     name[len] = cc;
  2708.     if (fname != name && fname != fname_buf)
  2709.     vim_free(fname);
  2710.  
  2711.     return ret;
  2712. }
  2713.  
  2714. /*********************************************
  2715.  * Implementation of the built-in functions
  2716.  */
  2717.  
  2718. /*
  2719.  * "append(lnum, string)" function
  2720.  */
  2721.     static void
  2722. f_append(argvars, retvar)
  2723.     VAR        argvars;
  2724.     VAR        retvar;
  2725. {
  2726.     long    lnum;
  2727.  
  2728.     lnum = get_var_lnum(argvars);
  2729.     retvar->var_val.var_number = 1; /* Default: Failed */
  2730.  
  2731.     if (lnum >= 0
  2732.         && lnum <= curbuf->b_ml.ml_line_count
  2733.         && u_save(lnum, lnum + 1) == OK)
  2734.     {
  2735.     ml_append(lnum, get_var_string(&argvars[1]), (colnr_T)0, FALSE);
  2736.     if (curwin->w_cursor.lnum > lnum)
  2737.         ++curwin->w_cursor.lnum;
  2738.     appended_lines_mark(lnum, 1L);
  2739.     retvar->var_val.var_number = 0;
  2740.     }
  2741. }
  2742.  
  2743. /*
  2744.  * "argc()" function
  2745.  */
  2746. /* ARGSUSED */
  2747.     static void
  2748. f_argc(argvars, retvar)
  2749.     VAR        argvars;
  2750.     VAR        retvar;
  2751. {
  2752.     retvar->var_val.var_number = ARGCOUNT;
  2753. }
  2754.  
  2755. /*
  2756.  * "argidx()" function
  2757.  */
  2758. /* ARGSUSED */
  2759.     static void
  2760. f_argidx(argvars, retvar)
  2761.     VAR        argvars;
  2762.     VAR        retvar;
  2763. {
  2764.     retvar->var_val.var_number = curwin->w_arg_idx;
  2765. }
  2766.  
  2767. /*
  2768.  * "argv(nr)" function
  2769.  */
  2770.     static void
  2771. f_argv(argvars, retvar)
  2772.     VAR        argvars;
  2773.     VAR        retvar;
  2774. {
  2775.     int        idx;
  2776.  
  2777.     idx = get_var_number(&argvars[0]);
  2778.     if (idx >= 0 && idx < ARGCOUNT)
  2779.     retvar->var_val.var_string = vim_strsave(alist_name(&ARGLIST[idx]));
  2780.     else
  2781.     retvar->var_val.var_string = NULL;
  2782.     retvar->var_type = VAR_STRING;
  2783. }
  2784.  
  2785. /*
  2786.  * "browse(save, title, initdir, default)" function
  2787.  */
  2788. /* ARGSUSED */
  2789.     static void
  2790. f_browse(argvars, retvar)
  2791.     VAR        argvars;
  2792.     VAR        retvar;
  2793. {
  2794. #ifdef FEAT_BROWSE
  2795.     int        save;
  2796.     char_u    *title;
  2797.     char_u    *initdir;
  2798.     char_u    *defname;
  2799.     char_u    buf[NUMBUFLEN];
  2800.     char_u    buf2[NUMBUFLEN];
  2801.  
  2802.     save = get_var_number(&argvars[0]);
  2803.     title = get_var_string(&argvars[1]);
  2804.     initdir = get_var_string_buf(&argvars[2], buf);
  2805.     defname = get_var_string_buf(&argvars[3], buf2);
  2806.  
  2807.     retvar->var_val.var_string =
  2808.          do_browse(save, title, defname, NULL, initdir, NULL, curbuf);
  2809. #else
  2810.     retvar->var_val.var_string = NULL;
  2811. #endif
  2812.     retvar->var_type = VAR_STRING;
  2813. }
  2814.  
  2815. /*
  2816.  * Find a buffer by number or exact name.
  2817.  */
  2818.     static buf_T *
  2819. find_buffer(avar)
  2820.     VAR        avar;
  2821. {
  2822.     buf_T    *buf = NULL;
  2823.     char_u    *name;
  2824.  
  2825.     if (avar->var_type == VAR_NUMBER)
  2826.     buf = buflist_findnr((int)avar->var_val.var_number);
  2827.     else if (avar->var_val.var_string != NULL)
  2828.     {
  2829.     /* First make the name into a full path name */
  2830.     name = FullName_save(avar->var_val.var_string,
  2831. #ifdef UNIX
  2832.         TRUE        /* force expansion, get rid of symbolic links */
  2833. #else
  2834.         FALSE
  2835. #endif
  2836.         );
  2837.     if (name != NULL)
  2838.     {
  2839.         buf = buflist_findname(name);
  2840.         vim_free(name);
  2841.     }
  2842.     }
  2843.     return buf;
  2844. }
  2845.  
  2846. /*
  2847.  * "bufexists(expr)" function
  2848.  */
  2849.     static void
  2850. f_bufexists(argvars, retvar)
  2851.     VAR        argvars;
  2852.     VAR        retvar;
  2853. {
  2854.     retvar->var_val.var_number = (find_buffer(&argvars[0]) != NULL);
  2855. }
  2856.  
  2857. /*
  2858.  * "buflisted(expr)" function
  2859.  */
  2860.     static void
  2861. f_buflisted(argvars, retvar)
  2862.     VAR        argvars;
  2863.     VAR        retvar;
  2864. {
  2865.     buf_T    *buf;
  2866.  
  2867.     buf = find_buffer(&argvars[0]);
  2868.     retvar->var_val.var_number = (buf != NULL && buf->b_p_bl);
  2869. }
  2870.  
  2871. /*
  2872.  * "bufloaded(expr)" function
  2873.  */
  2874.     static void
  2875. f_bufloaded(argvars, retvar)
  2876.     VAR        argvars;
  2877.     VAR        retvar;
  2878. {
  2879.     buf_T    *buf;
  2880.  
  2881.     buf = find_buffer(&argvars[0]);
  2882.     retvar->var_val.var_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
  2883. }
  2884.  
  2885. /*
  2886.  * Get buffer by number or pattern.
  2887.  */
  2888.     static buf_T *
  2889. get_buf_var(avar)
  2890.     VAR        avar;
  2891. {
  2892.     char_u    *name = avar->var_val.var_string;
  2893.     int        save_magic;
  2894.     char_u    *save_cpo;
  2895.     buf_T    *buf;
  2896.  
  2897.     if (avar->var_type == VAR_NUMBER)
  2898.     return buflist_findnr((int)avar->var_val.var_number);
  2899.     if (name == NULL || *name == NUL)
  2900.     return curbuf;
  2901.     if (name[0] == '$' && name[1] == NUL)
  2902.     return lastbuf;
  2903.  
  2904.     /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
  2905.     save_magic = p_magic;
  2906.     p_magic = TRUE;
  2907.     save_cpo = p_cpo;
  2908.     p_cpo = (char_u *)"";
  2909.  
  2910.     buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
  2911.                                    FALSE, FALSE));
  2912.  
  2913.     p_magic = save_magic;
  2914.     p_cpo = save_cpo;
  2915.     return buf;
  2916. }
  2917.  
  2918. /*
  2919.  * "bufname(expr)" function
  2920.  */
  2921.     static void
  2922. f_bufname(argvars, retvar)
  2923.     VAR        argvars;
  2924.     VAR        retvar;
  2925. {
  2926.     buf_T    *buf;
  2927.  
  2928.     ++emsg_off;
  2929.     buf = get_buf_var(&argvars[0]);
  2930.     retvar->var_type = VAR_STRING;
  2931.     if (buf != NULL && buf->b_fname != NULL)
  2932.     retvar->var_val.var_string = vim_strsave(buf->b_fname);
  2933.     else
  2934.     retvar->var_val.var_string = NULL;
  2935.     --emsg_off;
  2936. }
  2937.  
  2938. /*
  2939.  * "bufnr(expr)" function
  2940.  */
  2941.     static void
  2942. f_bufnr(argvars, retvar)
  2943.     VAR        argvars;
  2944.     VAR        retvar;
  2945. {
  2946.     buf_T    *buf;
  2947.  
  2948.     ++emsg_off;
  2949.     buf = get_buf_var(&argvars[0]);
  2950.     if (buf != NULL)
  2951.     retvar->var_val.var_number = buf->b_fnum;
  2952.     else
  2953.     retvar->var_val.var_number = -1;
  2954.     --emsg_off;
  2955. }
  2956.  
  2957. /*
  2958.  * "bufwinnr(nr)" function
  2959.  */
  2960.     static void
  2961. f_bufwinnr(argvars, retvar)
  2962.     VAR        argvars;
  2963.     VAR        retvar;
  2964. {
  2965. #ifdef FEAT_WINDOWS
  2966.     win_T    *wp;
  2967.     int        winnr = 0;
  2968. #endif
  2969.     buf_T    *buf;
  2970.  
  2971.     ++emsg_off;
  2972.     buf = get_buf_var(&argvars[0]);
  2973. #ifdef FEAT_WINDOWS
  2974.     for (wp = firstwin; wp; wp = wp->w_next)
  2975.     {
  2976.     ++winnr;
  2977.     if (wp->w_buffer == buf)
  2978.         break;
  2979.     }
  2980.     retvar->var_val.var_number = (wp != NULL ? winnr : -1);
  2981. #else
  2982.     retvar->var_val.var_number = (curwin->w_buffer == buf ? 1 : -1);
  2983. #endif
  2984.     --emsg_off;
  2985. }
  2986.  
  2987. /*
  2988.  * "byte2line(byte)" function
  2989.  */
  2990. /*ARGSUSED*/
  2991.     static void
  2992. f_byte2line(argvars, retvar)
  2993.     VAR        argvars;
  2994.     VAR        retvar;
  2995. {
  2996. #ifndef FEAT_BYTEOFF
  2997.     retvar->var_val.var_number = -1;
  2998. #else
  2999.     long    boff = 0;
  3000.  
  3001.     boff = get_var_number(&argvars[0]) - 1;
  3002.     if (boff < 0)
  3003.     retvar->var_val.var_number = -1;
  3004.     else
  3005.     retvar->var_val.var_number = ml_find_line_or_offset(curbuf,
  3006.                               (linenr_T)0, &boff);
  3007. #endif
  3008. }
  3009.  
  3010. /*
  3011.  * "char2nr(string)" function
  3012.  */
  3013.     static void
  3014. f_char2nr(argvars, retvar)
  3015.     VAR        argvars;
  3016.     VAR        retvar;
  3017. {
  3018.     retvar->var_val.var_number = get_var_string(&argvars[0])[0];
  3019. }
  3020.  
  3021. /*
  3022.  * "cindent(lnum)" function
  3023.  */
  3024.     static void
  3025. f_cindent(argvars, retvar)
  3026.     VAR        argvars;
  3027.     VAR        retvar;
  3028. {
  3029. #ifdef FEAT_CINDENT
  3030.     pos_T    pos;
  3031.     linenr_T    lnum;
  3032.  
  3033.     pos = curwin->w_cursor;
  3034.     lnum = get_var_lnum(argvars);
  3035.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  3036.     {
  3037.     curwin->w_cursor.lnum = lnum;
  3038.     retvar->var_val.var_number = get_c_indent();
  3039.     curwin->w_cursor = pos;
  3040.     }
  3041.     else
  3042. #endif
  3043.     retvar->var_val.var_number = -1;
  3044. }
  3045.  
  3046. /*
  3047.  * "col(string)" function
  3048.  */
  3049.     static void
  3050. f_col(argvars, retvar)
  3051.     VAR        argvars;
  3052.     VAR        retvar;
  3053. {
  3054.     colnr_T    col = 0;
  3055.     pos_T    *fp;
  3056.  
  3057.     fp = var2fpos(&argvars[0], FALSE);
  3058.     if (fp != NULL)
  3059.     col = fp->col + 1;
  3060.     retvar->var_val.var_number = col;
  3061. }
  3062.  
  3063. /*
  3064.  * "confirm(message, buttons[, default [, type]])" function
  3065.  */
  3066. /*ARGSUSED*/
  3067.     static void
  3068. f_confirm(argvars, retvar)
  3069.     VAR        argvars;
  3070.     VAR        retvar;
  3071. {
  3072. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  3073.     char_u    *message;
  3074.     char_u    *buttons;
  3075.     char_u    buf[NUMBUFLEN];
  3076.     char_u    buf2[NUMBUFLEN];
  3077.     int        def = 0;
  3078.     int        type = VIM_GENERIC;
  3079.     int        c;
  3080.  
  3081.     message = get_var_string(&argvars[0]);
  3082.     buttons = get_var_string_buf(&argvars[1], buf);
  3083.     if (argvars[2].var_type != VAR_UNKNOWN)
  3084.     {
  3085.     def = get_var_number(&argvars[2]);
  3086.     if (argvars[3].var_type != VAR_UNKNOWN)
  3087.     {
  3088.         /* avoid that TO_UPPER calls get_var_string_buf() twice */
  3089.         c = *get_var_string_buf(&argvars[3], buf2);
  3090.         switch (TO_UPPER(c))
  3091.         {
  3092.         case 'E': type = VIM_ERROR; break;
  3093.         case 'Q': type = VIM_QUESTION; break;
  3094.         case 'I': type = VIM_INFO; break;
  3095.         case 'W': type = VIM_WARNING; break;
  3096.         case 'G': type = VIM_GENERIC; break;
  3097.         }
  3098.     }
  3099.     }
  3100.  
  3101.     retvar->var_val.var_number = do_dialog(type, NULL, message, buttons,
  3102.                                    def, NULL);
  3103. #else
  3104.     retvar->var_val.var_number = 0;
  3105. #endif
  3106. }
  3107.  
  3108.  
  3109. /*
  3110.  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
  3111.  *
  3112.  * Checks the existence of a cscope connection.
  3113.  */
  3114. /*ARGSUSED*/
  3115.     static void
  3116. f_cscope_connection(argvars, retvar)
  3117.     VAR        argvars;
  3118.     VAR        retvar;
  3119. {
  3120. #ifdef FEAT_CSCOPE
  3121.     int        num = 0;
  3122.     char_u    *dbpath = NULL;
  3123.     char_u    *prepend = NULL;
  3124.     char_u    buf[NUMBUFLEN];
  3125.  
  3126.     if (argvars[0].var_type != VAR_UNKNOWN
  3127.         && argvars[1].var_type != VAR_UNKNOWN)
  3128.     {
  3129.     num = (int)get_var_number(&argvars[0]);
  3130.     dbpath = get_var_string(&argvars[1]);
  3131.     if (argvars[2].var_type != VAR_UNKNOWN)
  3132.         prepend = get_var_string_buf(&argvars[2], buf);
  3133.     }
  3134.  
  3135.     retvar->var_val.var_number = cs_connection(num, dbpath, prepend);
  3136. #else
  3137.     retvar->var_val.var_number = 0;
  3138. #endif
  3139. }
  3140.  
  3141. /*
  3142.  * "libcall()" function
  3143.  */
  3144.     static void
  3145. f_libcall(argvars, retvar)
  3146.     VAR        argvars;
  3147.     VAR        retvar;
  3148. {
  3149.     libcall_common(argvars, retvar, VAR_STRING);
  3150. }
  3151.  
  3152. /*
  3153.  * "libcallnr()" function
  3154.  */
  3155.     static void
  3156. f_libcallnr(argvars, retvar)
  3157.     VAR        argvars;
  3158.     VAR        retvar;
  3159. {
  3160.     libcall_common(argvars, retvar, VAR_NUMBER);
  3161. }
  3162.  
  3163.     static void
  3164. libcall_common(argvars, retvar, type)
  3165.     VAR        argvars;
  3166.     VAR        retvar;
  3167.     int        type;
  3168. {
  3169. #ifdef FEAT_LIBCALL
  3170.     char_u        *string_in;
  3171.     char_u        **string_result;
  3172.     int            nr_result;
  3173. #endif
  3174.  
  3175.     retvar->var_type = type;
  3176.     if (type == VAR_NUMBER)
  3177.     retvar->var_val.var_number = 0;
  3178.     else
  3179.     retvar->var_val.var_string = NULL;
  3180.  
  3181. #ifdef FEAT_LIBCALL
  3182.     /* The first two args must be strings, otherwise its meaningless */
  3183.     if (argvars[0].var_type == VAR_STRING && argvars[1].var_type == VAR_STRING)
  3184.     {
  3185.     if (argvars[2].var_type == VAR_NUMBER)
  3186.         string_in = NULL;
  3187.     else
  3188.         string_in = argvars[2].var_val.var_string;
  3189.     if (type == VAR_NUMBER)
  3190.         string_result = NULL;
  3191.     else
  3192.         string_result = &retvar->var_val.var_string;
  3193.     if (mch_libcall(argvars[0].var_val.var_string,
  3194.                  argvars[1].var_val.var_string,
  3195.                  string_in,
  3196.                  argvars[2].var_val.var_number,
  3197.                  string_result,
  3198.                  &nr_result) == OK
  3199.         && type == VAR_NUMBER)
  3200.         retvar->var_val.var_number = nr_result;
  3201.     }
  3202. #endif
  3203. }
  3204.  
  3205. /*
  3206.  * "delete()" function
  3207.  */
  3208.     static void
  3209. f_delete(argvars, retvar)
  3210.     VAR        argvars;
  3211.     VAR        retvar;
  3212. {
  3213.     retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0]));
  3214. }
  3215.  
  3216. /*
  3217.  * "did_filetype()" function
  3218.  */
  3219. /*ARGSUSED*/
  3220.     static void
  3221. f_did_filetype(argvars, retvar)
  3222.     VAR        argvars;
  3223.     VAR        retvar;
  3224. {
  3225. #ifdef FEAT_AUTOCMD
  3226.     retvar->var_val.var_number = did_filetype;
  3227. #else
  3228.     retvar->var_val.var_number = 0;
  3229. #endif
  3230. }
  3231.  
  3232. /*
  3233.  * "escape({string}, {chars})" function
  3234.  */
  3235.     static void
  3236. f_escape(argvars, retvar)
  3237.     VAR        argvars;
  3238.     VAR        retvar;
  3239. {
  3240.     char_u    buf[NUMBUFLEN];
  3241.  
  3242.     retvar->var_val.var_string =
  3243.     vim_strsave_escaped(get_var_string(&argvars[0]),
  3244.         get_var_string_buf(&argvars[1], buf));
  3245.     retvar->var_type = VAR_STRING;
  3246. }
  3247.  
  3248. /*
  3249.  * "eventhandler()" function
  3250.  */
  3251. /*ARGSUSED*/
  3252.     static void
  3253. f_eventhandler(argvars, retvar)
  3254.     VAR        argvars;
  3255.     VAR        retvar;
  3256. {
  3257.     retvar->var_val.var_number = vgetc_busy;
  3258. }
  3259.  
  3260. /*
  3261.  * "executable()" function
  3262.  */
  3263.     static void
  3264. f_executable(argvars, retvar)
  3265.     VAR        argvars;
  3266.     VAR        retvar;
  3267. {
  3268.     retvar->var_val.var_number = mch_can_exe(get_var_string(&argvars[0]));
  3269. }
  3270.  
  3271. /*
  3272.  * "exists()" function
  3273.  */
  3274.     static void
  3275. f_exists(argvars, retvar)
  3276.     VAR        argvars;
  3277.     VAR        retvar;
  3278. {
  3279.     char_u    *p;
  3280.     char_u    *name;
  3281.     int        n = FALSE;
  3282.     int        len;
  3283.  
  3284.     p = get_var_string(&argvars[0]);
  3285.     if (*p == '$')            /* environment variable */
  3286.     {
  3287.     /* first try "normal" environment variables (fast) */
  3288.     if (mch_getenv(p + 1) != NULL)
  3289.         n = TRUE;
  3290.     else
  3291.     {
  3292.         /* try expanding things like $VIM and ${HOME} */
  3293.         p = expand_env_save(p);
  3294.         if (p != NULL && *p != '$')
  3295.         n = TRUE;
  3296.         vim_free(p);
  3297.     }
  3298.     }
  3299.     else if (*p == '&')            /* option */
  3300.     n = (get_option_var(&p, NULL, TRUE) == OK);
  3301.     else if (*p == '*')            /* internal or user defined function */
  3302.     {
  3303.     ++p;
  3304.     if (ASCII_ISUPPER(*p) || *p == '<' || (*p == 's' && p[1] == ':'))
  3305.     {
  3306.         p = trans_function_name(&p);
  3307.         if (p != NULL)
  3308.         {
  3309.         n = (find_func(p) != NULL);
  3310.         vim_free(p);
  3311.         }
  3312.     }
  3313.     else if (ASCII_ISLOWER(*p))
  3314.         n = (find_internal_func(p) >= 0);
  3315.     }
  3316.     else if (*p == ':')
  3317.     {
  3318.     n = cmd_exists(p + 1);
  3319.     }
  3320.     else if (*p == '#')
  3321.     {
  3322. #ifdef FEAT_AUTOCMD
  3323.     name = p + 1;
  3324.     p = vim_strchr(name, '#');
  3325.     if (p != NULL)
  3326.         n = au_exists(name, p, p + 1);
  3327.     else
  3328.         n = au_exists(name, name + STRLEN(name), NULL);
  3329. #endif
  3330.     }
  3331.     else                /* internal variable */
  3332.     {
  3333.     name = p;
  3334.     len = get_id_len(&p);
  3335.     if (len != 0)
  3336.         n = (get_var_var(name, len, NULL) == OK);
  3337.     }
  3338.  
  3339.     retvar->var_val.var_number = n;
  3340. }
  3341.  
  3342. /*
  3343.  * "expand()" function
  3344.  */
  3345.     static void
  3346. f_expand(argvars, retvar)
  3347.     VAR        argvars;
  3348.     VAR        retvar;
  3349. {
  3350.     char_u    *s;
  3351.     int        len;
  3352.     char_u    *errormsg;
  3353.     int        flags = WILD_SILENT|WILD_USE_NL;
  3354.     expand_T    xpc;
  3355.  
  3356.     retvar->var_type = VAR_STRING;
  3357.     s = get_var_string(&argvars[0]);
  3358.     if (*s == '%' || *s == '#' || *s == '<')
  3359.     {
  3360.     ++emsg_off;
  3361.     retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s);
  3362.     --emsg_off;
  3363.     }
  3364.     else
  3365.     {
  3366.     /* When the optional second argument is non-zero, don't remove matches
  3367.      * for 'suffixes' and 'wildignore' */
  3368.     if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1]))
  3369.         flags |= WILD_KEEP_ALL;
  3370.     xpc.xp_context = EXPAND_FILES;
  3371.     retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
  3372.     }
  3373. }
  3374.  
  3375. /*
  3376.  * "filereadable()" function
  3377.  */
  3378.     static void
  3379. f_filereadable(argvars, retvar)
  3380.     VAR        argvars;
  3381.     VAR        retvar;
  3382. {
  3383.     FILE    *fd;
  3384.     char_u    *p;
  3385.     int        n;
  3386.  
  3387.     p = get_var_string(&argvars[0]);
  3388.     if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL)
  3389.     {
  3390.     n = TRUE;
  3391.     fclose(fd);
  3392.     }
  3393.     else
  3394.     n = FALSE;
  3395.  
  3396.     retvar->var_val.var_number = n;
  3397. }
  3398.  
  3399. /*
  3400.  * return 0 for not writable, 1 for writable file, 2 for a dir which we have
  3401.  * rights to write into.
  3402.  */
  3403.     static void
  3404. f_filewritable(argvars, retvar)
  3405.     VAR        argvars;
  3406.     VAR        retvar;
  3407. {
  3408.     char_u    *p;
  3409.     int        retval = 0;
  3410. #ifdef UNIX
  3411.     int        perm = 0;
  3412. #endif
  3413.  
  3414.     p = get_var_string(&argvars[0]);
  3415. #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
  3416. #ifdef WIN3264
  3417.     if (mch_writable(p))
  3418. #else
  3419. # ifdef UNIX
  3420.     perm = mch_getperm(p);
  3421. # endif
  3422.     if (
  3423. # ifdef UNIX
  3424.         (perm & 0222) &&
  3425. # endif
  3426.         mch_access((char *)p, W_OK) == 0
  3427.        )
  3428. #endif
  3429. #endif
  3430.     {
  3431.     ++retval;
  3432.     if (mch_isdir(p))
  3433.         ++retval;
  3434.     }
  3435.     retvar->var_val.var_number = retval;
  3436. }
  3437.  
  3438. /*
  3439.  * "fnamemodify({fname}, {mods})" function
  3440.  */
  3441.     static void
  3442. f_fnamemodify(argvars, retvar)
  3443.     VAR        argvars;
  3444.     VAR        retvar;
  3445. {
  3446.     char_u    *fname;
  3447.     char_u    *mods;
  3448.     int        usedlen = 0;
  3449.     int        len;
  3450.     char_u    *fbuf = NULL;
  3451.     char_u    buf[NUMBUFLEN];
  3452.  
  3453.     fname = get_var_string(&argvars[0]);
  3454.     mods = get_var_string_buf(&argvars[1], buf);
  3455.     len = (int)STRLEN(fname);
  3456.  
  3457.     (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
  3458.  
  3459.     retvar->var_type = VAR_STRING;
  3460.     if (fname == NULL)
  3461.     retvar->var_val.var_string = NULL;
  3462.     else
  3463.     retvar->var_val.var_string = vim_strnsave(fname, len);
  3464.     vim_free(fbuf);
  3465. }
  3466.  
  3467. /*
  3468.  * "foldclosed()" function
  3469.  */
  3470.     static void
  3471. f_foldclosed(argvars, retvar)
  3472.     VAR        argvars;
  3473.     VAR        retvar;
  3474. {
  3475.     foldclosed_both(argvars, retvar, FALSE);
  3476. }
  3477.  
  3478. /*
  3479.  * "foldclosedend()" function
  3480.  */
  3481.     static void
  3482. f_foldclosedend(argvars, retvar)
  3483.     VAR        argvars;
  3484.     VAR        retvar;
  3485. {
  3486.     foldclosed_both(argvars, retvar, TRUE);
  3487. }
  3488.  
  3489. /*
  3490.  * "foldclosed()" function
  3491.  */
  3492.     static void
  3493. foldclosed_both(argvars, retvar, end)
  3494.     VAR        argvars;
  3495.     VAR        retvar;
  3496.     int        end;
  3497. {
  3498. #ifdef FEAT_FOLDING
  3499.     linenr_T    lnum;
  3500.     linenr_T    first, last;
  3501.  
  3502.     lnum = get_var_lnum(argvars);
  3503.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  3504.     {
  3505.     if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
  3506.     {
  3507.         if (end)
  3508.         retvar->var_val.var_number = (varnumber_T)last;
  3509.         else
  3510.         retvar->var_val.var_number = (varnumber_T)first;
  3511.         return;
  3512.     }
  3513.     }
  3514. #endif
  3515.     retvar->var_val.var_number = -1;
  3516. }
  3517.  
  3518. /*
  3519.  * "foldlevel()" function
  3520.  */
  3521.     static void
  3522. f_foldlevel(argvars, retvar)
  3523.     VAR        argvars;
  3524.     VAR        retvar;
  3525. {
  3526. #ifdef FEAT_FOLDING
  3527.     linenr_T    lnum;
  3528.  
  3529.     lnum = get_var_lnum(argvars);
  3530.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  3531.     retvar->var_val.var_number = foldLevel(lnum);
  3532.     else
  3533. #endif
  3534.     retvar->var_val.var_number = 0;
  3535. }
  3536.  
  3537. /*
  3538.  * "foldtext()" function
  3539.  */
  3540. /*ARGSUSED*/
  3541.     static void
  3542. f_foldtext(argvars, retvar)
  3543.     VAR        argvars;
  3544.     VAR        retvar;
  3545. {
  3546. #ifdef FEAT_FOLDING
  3547.     linenr_T    lnum;
  3548.     char_u    *s;
  3549.     char_u    *r;
  3550.     int        len;
  3551.     char    *txt;
  3552. #endif
  3553.  
  3554.     retvar->var_type = VAR_STRING;
  3555.     retvar->var_val.var_string = NULL;
  3556. #ifdef FEAT_FOLDING
  3557.     if ((linenr_T)vimvars[VV_FOLDSTART].val > 0
  3558.         && (linenr_T)vimvars[VV_FOLDEND].val <= curbuf->b_ml.ml_line_count
  3559.         && vimvars[VV_FOLDDASHES].val != NULL)
  3560.     {
  3561.     /* Find first non-empty line in the fold. */
  3562.     lnum = (linenr_T)vimvars[VV_FOLDSTART].val;
  3563.     while (lnum < (linenr_T)vimvars[VV_FOLDEND].val)
  3564.     {
  3565.         if (!linewhite(lnum))
  3566.         break;
  3567.         ++lnum;
  3568.     }
  3569.  
  3570.     /* Find interesting text in this line. */
  3571.     s = skipwhite(ml_get(lnum));
  3572.     /* skip C comment-start */
  3573.     if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
  3574.         s = skipwhite(s + 2);
  3575.     txt = _("+-%s%3ld lines: ");
  3576.     r = alloc((unsigned)(STRLEN(s)
  3577.              + STRLEN(vimvars[VV_FOLDDASHES].val) + STRLEN(txt)));
  3578.     if (r != NULL)
  3579.     {
  3580.         sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].val,
  3581.             (long)((linenr_T)vimvars[VV_FOLDEND].val
  3582.                    - (linenr_T)vimvars[VV_FOLDSTART].val + 1));
  3583.         len = (int)STRLEN(r);
  3584.         STRCAT(r, s);
  3585.         /* remove 'foldmarker' and 'commentstring' */
  3586.         foldtext_cleanup(r + len);
  3587.         retvar->var_val.var_string = r;
  3588.     }
  3589.     }
  3590. #endif
  3591. }
  3592.  
  3593. /*
  3594.  * "foreground()" function
  3595.  */
  3596. /*ARGSUSED*/
  3597.     static void
  3598. f_foreground(argvars, retvar)
  3599.     VAR        argvars;
  3600.     VAR        retvar;
  3601. {
  3602. #ifdef FEAT_GUI
  3603.     if (gui.in_use)
  3604.     gui_mch_set_foreground();
  3605. #else
  3606. # ifdef WIN32
  3607.     win32_set_foreground();
  3608. # endif
  3609. #endif
  3610. }
  3611.  
  3612. /*
  3613.  * "getchar()" function
  3614.  */
  3615.     static void
  3616. f_getchar(argvars, retvar)
  3617.     VAR        argvars;
  3618.     VAR        retvar;
  3619. {
  3620.     varnumber_T        n;
  3621.  
  3622.     ++no_mapping;
  3623.     ++allow_keys;
  3624.     if (argvars[0].var_type == VAR_UNKNOWN)
  3625.     /* getchar(): blocking wait. */
  3626.     n = safe_vgetc();
  3627.     else if (get_var_number(&argvars[0]) == 1)
  3628.     /* getchar(1): only check if char avail */
  3629.     n = vpeekc();
  3630.     else if (vpeekc() == NUL)
  3631.     /* getchar(0) and no char avail: return zero */
  3632.     n = 0;
  3633.     else
  3634.     /* getchar(0) and char avail: return char */
  3635.     n = safe_vgetc();
  3636.     --no_mapping;
  3637.     --allow_keys;
  3638.  
  3639.     retvar->var_val.var_number = n;
  3640.     if (IS_SPECIAL(n) || mod_mask != 0)
  3641.     {
  3642.     char_u        temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
  3643.     int        i = 0;
  3644.  
  3645.     /* Turn a special key into three bytes, plus modifier. */
  3646.     if (mod_mask != 0)
  3647.     {
  3648.         temp[i++] = K_SPECIAL;
  3649.         temp[i++] = KS_MODIFIER;
  3650.         temp[i++] = mod_mask;
  3651.     }
  3652.     if (IS_SPECIAL(n))
  3653.     {
  3654.         temp[i++] = K_SPECIAL;
  3655.         temp[i++] = K_SECOND(n);
  3656.         temp[i++] = K_THIRD(n);
  3657.     }
  3658. #ifdef FEAT_MBYTE
  3659.     else if (has_mbyte)
  3660.         i += (*mb_char2bytes)(n, temp + i);
  3661. #endif
  3662.     else
  3663.         temp[i++] = n;
  3664.     temp[i++] = NUL;
  3665.     retvar->var_type = VAR_STRING;
  3666.     retvar->var_val.var_string = vim_strsave(temp);
  3667.     }
  3668. }
  3669.  
  3670. /*
  3671.  * "getcharmod()" function
  3672.  */
  3673. /*ARGSUSED*/
  3674.     static void
  3675. f_getcharmod(argvars, retvar)
  3676.     VAR        argvars;
  3677.     VAR        retvar;
  3678. {
  3679.     retvar->var_val.var_number = mod_mask;
  3680. }
  3681.  
  3682. /*
  3683.  * "getbufvar()" function
  3684.  */
  3685.     static void
  3686. f_getbufvar(argvars, retvar)
  3687.     VAR        argvars;
  3688.     VAR        retvar;
  3689. {
  3690.     buf_T    *buf;
  3691.     buf_T    *save_curbuf;
  3692.     char_u    *varname;
  3693.     VAR        v;
  3694.  
  3695.     ++emsg_off;
  3696.     buf = get_buf_var(&argvars[0]);
  3697.     varname = get_var_string(&argvars[1]);
  3698.  
  3699.     retvar->var_type = VAR_STRING;
  3700.     retvar->var_val.var_string = NULL;
  3701.  
  3702.     if (buf != NULL && varname != NULL)
  3703.     {
  3704.     if (*varname == '&')    /* buffer-local-option */
  3705.     {
  3706.         /* set curbuf to be our buf, temporarily */
  3707.         save_curbuf = curbuf;
  3708.         curbuf = buf;
  3709.  
  3710.         get_option_var(&varname, retvar, TRUE);
  3711.  
  3712.         /* restore previous notion of curbuf */
  3713.         curbuf = save_curbuf;
  3714.     }
  3715.     else
  3716.     {
  3717.         /* look up the variable */
  3718.         v = find_var_in_ga(&buf->b_vars, varname);
  3719.         if (v != NULL)
  3720.         copy_var(v, retvar);
  3721.     }
  3722.     }
  3723.  
  3724.     --emsg_off;
  3725. }
  3726.  
  3727. /*
  3728.  * "getcwd()" function
  3729.  */
  3730. /*ARGSUSED*/
  3731.     static void
  3732. f_getcwd(argvars, retvar)
  3733.     VAR        argvars;
  3734.     VAR        retvar;
  3735. {
  3736.     char_u    cwd[MAXPATHL];
  3737.  
  3738.     retvar->var_type = VAR_STRING;
  3739.     if (mch_dirname(cwd, MAXPATHL) == FAIL)
  3740.     retvar->var_val.var_string = NULL;
  3741.     else
  3742.     retvar->var_val.var_string = vim_strsave(cwd);
  3743. }
  3744.  
  3745. /*
  3746.  * "getftime({fname})" function
  3747.  */
  3748.     static void
  3749. f_getftime(argvars, retvar)
  3750.     VAR        argvars;
  3751.     VAR        retvar;
  3752. {
  3753.     char_u    *fname;
  3754.     struct stat    st;
  3755.  
  3756.     fname = get_var_string(&argvars[0]);
  3757.  
  3758.     if (mch_stat((char *)fname, &st) >= 0)
  3759.     retvar->var_val.var_number = (varnumber_T)st.st_mtime;
  3760.     else
  3761.     retvar->var_val.var_number = -1;
  3762. }
  3763.  
  3764. /*
  3765.  * "getfsize({fname})" function
  3766.  */
  3767.     static void
  3768. f_getfsize(argvars, retvar)
  3769.     VAR        argvars;
  3770.     VAR        retvar;
  3771. {
  3772.     char_u    *fname;
  3773.     struct stat    st;
  3774.  
  3775.     fname = get_var_string(&argvars[0]);
  3776.  
  3777.     retvar->var_type = VAR_NUMBER;
  3778.  
  3779.     if (mch_stat((char *)fname, &st) >= 0)
  3780.     {
  3781.     if (mch_isdir(fname))
  3782.         retvar->var_val.var_number = 0;
  3783.     else
  3784.         retvar->var_val.var_number = (varnumber_T)st.st_size;
  3785.     }
  3786.     else
  3787.       retvar->var_val.var_number = -1;
  3788. }
  3789.  
  3790. /*
  3791.  * "getline(lnum)" function
  3792.  */
  3793.     static void
  3794. f_getline(argvars, retvar)
  3795.     VAR        argvars;
  3796.     VAR        retvar;
  3797. {
  3798.     linenr_T    lnum;
  3799.     char_u    *p;
  3800.  
  3801.     lnum = get_var_lnum(argvars);
  3802.  
  3803.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  3804.     p = ml_get(lnum);
  3805.     else
  3806.     p = (char_u *)"";
  3807.  
  3808.     retvar->var_type = VAR_STRING;
  3809.     retvar->var_val.var_string = vim_strsave(p);
  3810. }
  3811.  
  3812. /*
  3813.  * "getwinposx()" function
  3814.  */
  3815. /*ARGSUSED*/
  3816.     static void
  3817. f_getwinposx(argvars, retvar)
  3818.     VAR        argvars;
  3819.     VAR        retvar;
  3820. {
  3821.     retvar->var_val.var_number = -1;
  3822. #ifdef FEAT_GUI
  3823.     if (gui.in_use)
  3824.     {
  3825.     int        x, y;
  3826.  
  3827.     if (gui_mch_get_winpos(&x, &y) == OK)
  3828.         retvar->var_val.var_number = x;
  3829.     }
  3830. #endif
  3831. }
  3832.  
  3833. /*
  3834.  * "getwinposy()" function
  3835.  */
  3836. /*ARGSUSED*/
  3837.     static void
  3838. f_getwinposy(argvars, retvar)
  3839.     VAR        argvars;
  3840.     VAR        retvar;
  3841. {
  3842.     retvar->var_val.var_number = -1;
  3843. #ifdef FEAT_GUI
  3844.     if (gui.in_use)
  3845.     {
  3846.     int        x, y;
  3847.  
  3848.     if (gui_mch_get_winpos(&x, &y) == OK)
  3849.         retvar->var_val.var_number = y;
  3850.     }
  3851. #endif
  3852. }
  3853.  
  3854. /*
  3855.  * "getwinvar()" function
  3856.  */
  3857.     static void
  3858. f_getwinvar(argvars, retvar)
  3859.     VAR        argvars;
  3860.     VAR        retvar;
  3861. {
  3862.     win_T    *win, *oldcurwin;
  3863.     char_u    *varname;
  3864.     VAR        v;
  3865.  
  3866.     ++emsg_off;
  3867.     win = find_win_by_nr(&argvars[0]);
  3868.     varname = get_var_string(&argvars[1]);
  3869.  
  3870.     retvar->var_type = VAR_STRING;
  3871.     retvar->var_val.var_string = NULL;
  3872.  
  3873.     if (win != NULL && varname != NULL)
  3874.     {
  3875.     if (*varname == '&')    /* window-local-option */
  3876.     {
  3877.         /* set curwin to be our win, temporarily */
  3878.         oldcurwin = curwin;
  3879.         curwin = win;
  3880.  
  3881.         get_option_var(&varname, retvar , 1);
  3882.  
  3883.         /* restore previous notion of curwin */
  3884.         curwin = oldcurwin;
  3885.     }
  3886.     else
  3887.     {
  3888.         /* look up the variable */
  3889.         v = find_var_in_ga(&win->w_vars, varname);
  3890.         if (v != NULL)
  3891.         copy_var(v, retvar);
  3892.     }
  3893.     }
  3894.  
  3895.     --emsg_off;
  3896. }
  3897.  
  3898. /*
  3899.  * "glob()" function
  3900.  */
  3901.     static void
  3902. f_glob(argvars, retvar)
  3903.     VAR        argvars;
  3904.     VAR        retvar;
  3905. {
  3906.     expand_T    xpc;
  3907.  
  3908.     xpc.xp_context = EXPAND_FILES;
  3909.     retvar->var_type = VAR_STRING;
  3910.     retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]),
  3911.                      NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
  3912. }
  3913.  
  3914. /*
  3915.  * "globpath()" function
  3916.  */
  3917.     static void
  3918. f_globpath(argvars, retvar)
  3919.     VAR        argvars;
  3920.     VAR        retvar;
  3921. {
  3922.     char_u    buf1[NUMBUFLEN];
  3923.  
  3924.     retvar->var_type = VAR_STRING;
  3925.     retvar->var_val.var_string = globpath(get_var_string(&argvars[0]),
  3926.                        get_var_string_buf(&argvars[1], buf1));
  3927. }
  3928.  
  3929. /*
  3930.  * "has()" function
  3931.  */
  3932.     static void
  3933. f_has(argvars, retvar)
  3934.     VAR        argvars;
  3935.     VAR        retvar;
  3936. {
  3937.     int        i;
  3938.     char_u    *name;
  3939.     int        n = FALSE;
  3940.     static char    *(has_list[]) =
  3941.     {
  3942. #ifdef AMIGA
  3943.     "amiga",
  3944. # ifdef FEAT_ARP
  3945.     "arp",
  3946. # endif
  3947. #endif
  3948. #ifdef __BEOS__
  3949.     "beos",
  3950. #endif
  3951. #ifdef MSDOS
  3952. # ifdef DJGPP
  3953.     "dos32",
  3954. # else
  3955.     "dos16",
  3956. # endif
  3957. #endif
  3958. #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */
  3959.     "mac",
  3960. #endif
  3961. #ifdef OS2
  3962.     "os2",
  3963. #endif
  3964. #ifdef __QNX__
  3965.     "qnx",
  3966. #endif
  3967. #ifdef RISCOS
  3968.     "riscos",
  3969. #endif
  3970. #ifdef UNIX
  3971.     "unix",
  3972. #endif
  3973. #ifdef VMS
  3974.     "vms",
  3975. #endif
  3976. #ifdef WIN16
  3977.     "win16",
  3978. #endif
  3979. #ifdef WIN32
  3980.     "win32",
  3981. #endif
  3982. #ifdef WIN64
  3983.     "win64",
  3984. #endif
  3985. #ifdef EBCDIC
  3986.     "ebcdic",
  3987. #endif
  3988. #ifndef CASE_INSENSITIVE_FILENAME
  3989.     "fname_case",
  3990. #endif
  3991. #ifdef FEAT_AUTOCMD
  3992.     "autocmd",
  3993. #endif
  3994. #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
  3995.     "builtin_terms",
  3996. # ifdef ALL_BUILTIN_TCAPS
  3997.     "all_builtin_terms",
  3998. # endif
  3999. #endif
  4000. #ifdef FEAT_BYTEOFF
  4001.     "byte_offset",
  4002. #endif
  4003. #ifdef FEAT_CINDENT
  4004.     "cindent",
  4005. #endif
  4006. #ifdef FEAT_CLIENTSERVER
  4007.     "clientserver",
  4008. #endif
  4009. #ifdef FEAT_CLIPBOARD
  4010.     "clipboard",
  4011. #endif
  4012. #ifdef FEAT_CMDL_COMPL
  4013.     "cmdline_compl",
  4014. #endif
  4015. #ifdef FEAT_CMDHIST
  4016.     "cmdline_hist",
  4017. #endif
  4018. #ifdef FEAT_COMMENTS
  4019.     "comments",
  4020. #endif
  4021. #ifdef FEAT_CRYPT
  4022.     "cryptv",
  4023. #endif
  4024. #ifdef FEAT_CSCOPE
  4025.     "cscope",
  4026. #endif
  4027. #ifdef DEBUG
  4028.     "debug",
  4029. #endif
  4030. #ifdef FEAT_CON_DIALOG
  4031.     "dialog_con",
  4032. #endif
  4033. #ifdef FEAT_GUI_DIALOG
  4034.     "dialog_gui",
  4035. #endif
  4036. #ifdef FEAT_DIFF
  4037.     "diff",
  4038. #endif
  4039. #ifdef FEAT_DIGRAPHS
  4040.     "digraphs",
  4041. #endif
  4042. #ifdef FEAT_EMACS_TAGS
  4043.     "emacs_tags",
  4044. #endif
  4045.     "eval",        /* always present, of course! */
  4046. #ifdef FEAT_EX_EXTRA
  4047.     "ex_extra",
  4048. #endif
  4049. #ifdef FEAT_SEARCH_EXTRA
  4050.     "extra_search",
  4051. #endif
  4052. #ifdef FEAT_FKMAP
  4053.     "farsi",
  4054. #endif
  4055. #ifdef FEAT_SEARCHPATH
  4056.     "file_in_path",
  4057. #endif
  4058. #ifdef FEAT_FIND_ID
  4059.     "find_in_path",
  4060. #endif
  4061. #ifdef FEAT_FOLDING
  4062.     "folding",
  4063. #endif
  4064. #ifdef FEAT_FOOTER
  4065.     "footer",
  4066. #endif
  4067. #if !defined(USE_SYSTEM) && defined(UNIX)
  4068.     "fork",
  4069. #endif
  4070. #ifdef FEAT_GETTEXT
  4071.     "gettext",
  4072. #endif
  4073. #ifdef FEAT_GUI
  4074.     "gui",
  4075. #endif
  4076. #ifdef FEAT_GUI_ATHENA
  4077.     "gui_athena",
  4078. #endif
  4079. #ifdef FEAT_GUI_BEOS
  4080.     "gui_beos",
  4081. #endif
  4082. #ifdef FEAT_GUI_GTK
  4083.     "gui_gtk",
  4084. #endif
  4085. #ifdef FEAT_GUI_MAC
  4086.     "gui_mac",
  4087. #endif
  4088. #ifdef FEAT_GUI_MOTIF
  4089.     "gui_motif",
  4090. #endif
  4091. #ifdef FEAT_GUI_PHOTON
  4092.     "gui_photon",
  4093. #endif
  4094. #ifdef FEAT_GUI_W16
  4095.     "gui_win16",
  4096. #endif
  4097. #ifdef FEAT_GUI_W32
  4098.     "gui_win32",
  4099. #endif
  4100. #ifdef FEAT_HANGULIN
  4101.     "hangul_input",
  4102. #endif
  4103. #if defined(HAVE_ICONV_H) && defined(USE_ICONV)
  4104.     "iconv",
  4105. #endif
  4106. #ifdef FEAT_INS_EXPAND
  4107.     "insert_expand",
  4108. #endif
  4109. #ifdef FEAT_JUMPLIST
  4110.     "jumplist",
  4111. #endif
  4112. #ifdef FEAT_KEYMAP
  4113.     "keymap",
  4114. #endif
  4115. #ifdef FEAT_LANGMAP
  4116.     "langmap",
  4117. #endif
  4118. #ifdef FEAT_LIBCALL
  4119.     "libcall",
  4120. #endif
  4121. #ifdef FEAT_LINEBREAK
  4122.     "linebreak",
  4123. #endif
  4124. #ifdef FEAT_LISP
  4125.     "lispindent",
  4126. #endif
  4127. #ifdef FEAT_LISTCMDS
  4128.     "listcmds",
  4129. #endif
  4130. #ifdef FEAT_LOCALMAP
  4131.     "localmap",
  4132. #endif
  4133. #ifdef FEAT_MENU
  4134.     "menu",
  4135. #endif
  4136. #ifdef FEAT_SESSION
  4137.     "mksession",
  4138. #endif
  4139. #ifdef FEAT_MODIFY_FNAME
  4140.     "modify_fname",
  4141. #endif
  4142. #ifdef FEAT_MOUSE
  4143.     "mouse",
  4144. #endif
  4145. #ifdef FEAT_MOUSESHAPE
  4146.     "mouseshape",
  4147. #endif
  4148. #if defined(UNIX) || defined(VMS)
  4149. # ifdef FEAT_MOUSE_DEC
  4150.     "mouse_dec",
  4151. # endif
  4152. # ifdef FEAT_MOUSE_GPM
  4153.     "mouse_gpm",
  4154. # endif
  4155. # ifdef FEAT_MOUSE_JSB
  4156.     "mouse_jsbterm",
  4157. # endif
  4158. # ifdef FEAT_MOUSE_NET
  4159.     "mouse_netterm",
  4160. # endif
  4161. # ifdef FEAT_MOUSE_PTERM
  4162.     "mouse_pterm",
  4163. # endif
  4164. # ifdef FEAT_MOUSE_XTERM
  4165.     "mouse_xterm",
  4166. # endif
  4167. #endif
  4168. #ifdef FEAT_MBYTE
  4169.     "multi_byte",
  4170. #endif
  4171. #ifdef FEAT_MBYTE_IME
  4172.     "multi_byte_ime",
  4173. #endif
  4174. #ifdef FEAT_MULTI_LANG
  4175.     "multi_lang",
  4176. #endif
  4177. #ifdef FEAT_OLE
  4178.     "ole",
  4179. #endif
  4180. #ifdef FEAT_OSFILETYPE
  4181.     "osfiletype",
  4182. #endif
  4183. #ifdef FEAT_PATH_EXTRA
  4184.     "path_extra",
  4185. #endif
  4186. #ifdef FEAT_PERL
  4187. #ifndef DYNAMIC_PERL
  4188.     "perl",
  4189. #endif
  4190. #endif
  4191. #ifdef FEAT_PYTHON
  4192. #ifndef DYNAMIC_PYTHON
  4193.     "python",
  4194. #endif
  4195. #endif
  4196. #ifdef FEAT_POSTSCRIPT
  4197.     "postscript",
  4198. #endif
  4199. #ifdef FEAT_PRINTER
  4200.     "printer",
  4201. #endif
  4202. #ifdef FEAT_QUICKFIX
  4203.     "quickfix",
  4204. #endif
  4205. #ifdef FEAT_RIGHTLEFT
  4206.     "rightleft",
  4207. #endif
  4208. #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
  4209.     "ruby",
  4210. #endif
  4211. #ifdef FEAT_SCROLLBIND
  4212.     "scrollbind",
  4213. #endif
  4214. #ifdef FEAT_CMDL_INFO
  4215.     "showcmd",
  4216.     "cmdline_info",
  4217. #endif
  4218. #ifdef FEAT_SIGNS
  4219.     "signs",
  4220. #endif
  4221. #ifdef FEAT_SMARTINDENT
  4222.     "smartindent",
  4223. #endif
  4224. #ifdef FEAT_SNIFF
  4225.     "sniff",
  4226. #endif
  4227. #ifdef FEAT_STL_OPT
  4228.     "statusline",
  4229. #endif
  4230. #ifdef FEAT_SUN_WORKSHOP
  4231.     "sun_workshop",
  4232. #endif
  4233. #ifdef FEAT_SYN_HL
  4234.     "syntax",
  4235. #endif
  4236. #if defined(USE_SYSTEM) || !defined(UNIX)
  4237.     "system",
  4238. #endif
  4239. #ifdef FEAT_TAG_BINS
  4240.     "tag_binary",
  4241. #endif
  4242. #ifdef FEAT_TAG_OLDSTATIC
  4243.     "tag_old_static",
  4244. #endif
  4245. #ifdef FEAT_TAG_ANYWHITE
  4246.     "tag_any_white",
  4247. #endif
  4248. #ifdef FEAT_TCL
  4249. # ifndef DYNAMIC_TCL
  4250.     "tcl",
  4251. # endif
  4252. #endif
  4253. #ifdef TERMINFO
  4254.     "terminfo",
  4255. #endif
  4256. #ifdef FEAT_TERMRESPONSE
  4257.     "termresponse",
  4258. #endif
  4259. #ifdef FEAT_TEXTOBJ
  4260.     "textobjects",
  4261. #endif
  4262. #ifdef HAVE_TGETENT
  4263.     "tgetent",
  4264. #endif
  4265. #ifdef FEAT_TITLE
  4266.     "title",
  4267. #endif
  4268. #ifdef FEAT_TOOLBAR
  4269.     "toolbar",
  4270. #endif
  4271. #ifdef FEAT_USR_CMDS
  4272.     "user-commands",    /* was accidentally included in 5.4 */
  4273.     "user_commands",
  4274. #endif
  4275. #ifdef FEAT_VIMINFO
  4276.     "viminfo",
  4277. #endif
  4278. #ifdef FEAT_VERTSPLIT
  4279.     "vertsplit",
  4280. #endif
  4281. #ifdef FEAT_VIRTUALEDIT
  4282.     "virtualedit",
  4283. #endif
  4284. #ifdef FEAT_VISUAL
  4285.     "visual",
  4286. #endif
  4287. #ifdef FEAT_VISUALEXTRA
  4288.     "visualextra",
  4289. #endif
  4290. #ifdef FEAT_VREPLACE
  4291.     "vreplace",
  4292. #endif
  4293. #ifdef FEAT_WILDIGN
  4294.     "wildignore",
  4295. #endif
  4296. #ifdef FEAT_WILDMENU
  4297.     "wildmenu",
  4298. #endif
  4299. #ifdef FEAT_WINDOWS
  4300.     "windows",
  4301. #endif
  4302. #ifdef FEAT_WAK
  4303.     "winaltkeys",
  4304. #endif
  4305. #ifdef FEAT_WRITEBACKUP
  4306.     "writebackup",
  4307. #endif
  4308. #ifdef FEAT_XIM
  4309.     "xim",
  4310. #endif
  4311. #ifdef FEAT_XFONTSET
  4312.     "xfontset",
  4313. #endif
  4314. #ifdef FEAT_XCLIPBOARD
  4315.     "xterm_clipboard",
  4316. #endif
  4317. #ifdef FEAT_XTERM_SAVE
  4318.     "xterm_save",
  4319. #endif
  4320. #if defined(UNIX) && defined(FEAT_X11)
  4321.     "X11",
  4322. #endif
  4323.     NULL
  4324.     };
  4325.  
  4326.     name = get_var_string(&argvars[0]);
  4327.     for (i = 0; has_list[i] != NULL; ++i)
  4328.     if (STRICMP(name, has_list[i]) == 0)
  4329.     {
  4330.         n = TRUE;
  4331.         break;
  4332.     }
  4333.  
  4334.     if (n == FALSE)
  4335.     {
  4336.     if (STRICMP(name, "vim_starting") == 0)
  4337.         n = (starting != 0);
  4338. #ifdef DYNAMIC_TCL
  4339.     else if (STRICMP(name, "tcl") == 0)
  4340.         n = tcl_enabled() ? TRUE : FALSE;
  4341. #endif
  4342. #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
  4343.     else if (STRICMP(name, "iconv") == 0)
  4344.         n = iconv_enabled();
  4345. #endif
  4346. #ifdef DYNAMIC_RUBY
  4347.     else if (STRICMP(name, "ruby") == 0)
  4348.         n = ruby_enabled() ? TRUE : FALSE;
  4349. #endif
  4350. #ifdef DYNAMIC_PYTHON
  4351.     else if (STRICMP(name, "python") == 0)
  4352.         n = python_enabled() ? TRUE : FALSE;
  4353. #endif
  4354. #ifdef DYNAMIC_PERL
  4355.     else if (STRICMP(name, "perl") == 0)
  4356.         n = perl_enabled() ? TRUE : FALSE;
  4357. #endif
  4358. #ifdef FEAT_GUI
  4359.     else if (STRICMP(name, "gui_running") == 0)
  4360.         n = (gui.in_use || gui.starting);
  4361. # ifdef FEAT_GUI_W32
  4362.     else if (STRICMP(name, "gui_win32s") == 0)
  4363.         n = gui_is_win32s();
  4364. # endif
  4365. # ifdef FEAT_BROWSE
  4366.     else if (STRICMP(name, "browse") == 0)
  4367.         n = gui.in_use;    /* gui_mch_browse() works when GUI is running */
  4368. # endif
  4369. #endif
  4370. #ifdef FEAT_SYN_HL
  4371.     else if (STRICMP(name, "syntax_items") == 0)
  4372.         n = syntax_present(curbuf);
  4373. #endif
  4374. #if defined(WIN3264)
  4375.     else if (STRICMP(name, "win95") == 0)
  4376.         n = mch_windows95();
  4377. #endif
  4378.     }
  4379.  
  4380.     retvar->var_val.var_number = n;
  4381. }
  4382.  
  4383. /*
  4384.  * "hasmapto()" function
  4385.  */
  4386.     static void
  4387. f_hasmapto(argvars, retvar)
  4388.     VAR        argvars;
  4389.     VAR        retvar;
  4390. {
  4391.     char_u    *name;
  4392.     char_u    *mode;
  4393.     char_u    buf[NUMBUFLEN];
  4394.  
  4395.     name = get_var_string(&argvars[0]);
  4396.     if (argvars[1].var_type == VAR_UNKNOWN)
  4397.     mode = (char_u *)"nvo";
  4398.     else
  4399.     mode = get_var_string_buf(&argvars[1], buf);
  4400.  
  4401.     if (map_to_exists(name, mode))
  4402.     retvar->var_val.var_number = TRUE;
  4403.     else
  4404.     retvar->var_val.var_number = FALSE;
  4405. }
  4406.  
  4407. /*
  4408.  * "histadd()" function
  4409.  */
  4410. /*ARGSUSED*/
  4411.     static void
  4412. f_histadd(argvars, retvar)
  4413.     VAR        argvars;
  4414.     VAR        retvar;
  4415. {
  4416. #ifdef FEAT_CMDHIST
  4417.     int        histype;
  4418.     char_u    *str;
  4419.     char_u    buf[NUMBUFLEN];
  4420.  
  4421.     histype = get_histtype(get_var_string(&argvars[0]));
  4422.     if (histype >= 0)
  4423.     {
  4424.     str = get_var_string_buf(&argvars[1], buf);
  4425.     if (*str != NUL)
  4426.     {
  4427.         add_to_history(histype, str, FALSE);
  4428.         retvar->var_val.var_number = TRUE;
  4429.         return;
  4430.     }
  4431.     }
  4432. #endif
  4433.     retvar->var_val.var_number = FALSE;
  4434. }
  4435.  
  4436. /*
  4437.  * "histdel()" function
  4438.  */
  4439. /*ARGSUSED*/
  4440.     static void
  4441. f_histdel(argvars, retvar)
  4442.     VAR        argvars;
  4443.     VAR        retvar;
  4444. {
  4445. #ifdef FEAT_CMDHIST
  4446.     int        n;
  4447.     char_u    buf[NUMBUFLEN];
  4448.  
  4449.     if (argvars[1].var_type == VAR_UNKNOWN)
  4450.     /* only one argument: clear entire history */
  4451.     n = clr_history(get_histtype(get_var_string(&argvars[0])));
  4452.     else if (argvars[1].var_type == VAR_NUMBER)
  4453.     /* index given: remove that entry */
  4454.     n = del_history_idx(get_histtype(get_var_string(&argvars[0])),
  4455.                         (int)get_var_number(&argvars[1]));
  4456.     else
  4457.     /* string given: remove all matching entries */
  4458.     n = del_history_entry(get_histtype(get_var_string(&argvars[0])),
  4459.                     get_var_string_buf(&argvars[1], buf));
  4460.     retvar->var_val.var_number = n;
  4461. #else
  4462.     retvar->var_val.var_number = 0;
  4463. #endif
  4464. }
  4465.  
  4466. /*
  4467.  * "histget()" function
  4468.  */
  4469. /*ARGSUSED*/
  4470.     static void
  4471. f_histget(argvars, retvar)
  4472.     VAR        argvars;
  4473.     VAR        retvar;
  4474. {
  4475. #ifdef FEAT_CMDHIST
  4476.     int        type;
  4477.     int        idx;
  4478.  
  4479.     type = get_histtype(get_var_string(&argvars[0]));
  4480.     retvar->var_type = VAR_STRING;
  4481.     if (argvars[1].var_type == VAR_UNKNOWN)
  4482.     idx = get_history_idx(type);
  4483.     else
  4484.     idx = (int)get_var_number(&argvars[1]);
  4485.     retvar->var_val.var_string = vim_strsave(get_history_entry(type, idx));
  4486. #endif
  4487. }
  4488.  
  4489. /*
  4490.  * "histnr()" function
  4491.  */
  4492. /*ARGSUSED*/
  4493.     static void
  4494. f_histnr(argvars, retvar)
  4495.     VAR        argvars;
  4496.     VAR        retvar;
  4497. {
  4498.     int        i;
  4499.  
  4500. #ifdef FEAT_CMDHIST
  4501.     i = get_histtype(get_var_string(&argvars[0]));
  4502.     if (i >= HIST_CMD && i < HIST_COUNT)
  4503.     i = get_history_idx(i);
  4504.     else
  4505. #endif
  4506.     i = -1;
  4507.     retvar->var_val.var_number = i;
  4508. }
  4509.  
  4510. /*
  4511.  * "highlight_exists()" function
  4512.  */
  4513.     static void
  4514. f_hlexists(argvars, retvar)
  4515.     VAR        argvars;
  4516.     VAR        retvar;
  4517. {
  4518.     retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0]));
  4519. }
  4520.  
  4521. /*
  4522.  * "highlightID(name)" function
  4523.  */
  4524.     static void
  4525. f_hlID(argvars, retvar)
  4526.     VAR        argvars;
  4527.     VAR        retvar;
  4528. {
  4529.     retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0]));
  4530. }
  4531.  
  4532. /*
  4533.  * "hostname()" function
  4534.  */
  4535. /*ARGSUSED*/
  4536.     static void
  4537. f_hostname(argvars, retvar)
  4538.     VAR        argvars;
  4539.     VAR        retvar;
  4540. {
  4541.     char_u hostname[256];
  4542.  
  4543.     mch_get_host_name(hostname, 256);
  4544.     retvar->var_type = VAR_STRING;
  4545.     retvar->var_val.var_string = vim_strsave(hostname);
  4546. }
  4547.  
  4548. /*
  4549.  * iconv() function
  4550.  */
  4551. /*ARGSUSED*/
  4552.     static void
  4553. f_iconv(argvars, retvar)
  4554.     VAR        argvars;
  4555.     VAR        retvar;
  4556. {
  4557. #ifdef FEAT_MBYTE
  4558.     char_u    buf1[NUMBUFLEN];
  4559.     char_u    buf2[NUMBUFLEN];
  4560.     char_u    *from, *to, *str;
  4561.     vimconv_T    vimconv;
  4562. #endif
  4563.  
  4564.     retvar->var_type = VAR_STRING;
  4565.     retvar->var_val.var_string = NULL;
  4566.  
  4567. #ifdef FEAT_MBYTE
  4568.     str = get_var_string(&argvars[0]);
  4569.     from = enc_canonize(enc_skip(get_var_string_buf(&argvars[1], buf1)));
  4570.     to = enc_canonize(enc_skip(get_var_string_buf(&argvars[2], buf2)));
  4571. # ifdef USE_ICONV
  4572.     vimconv.vc_fd = (iconv_t)-1;
  4573. # endif
  4574.     convert_setup(&vimconv, from, to);
  4575.  
  4576.     /* If the encodings are equal, no conversion needed. */
  4577.     if (vimconv.vc_type == CONV_NONE)
  4578.     retvar->var_val.var_string = vim_strsave(str);
  4579.     else
  4580.     retvar->var_val.var_string = string_convert(&vimconv, str, NULL);
  4581.  
  4582.     convert_setup(&vimconv, (char_u *)"", (char_u *)"");
  4583.     vim_free(from);
  4584.     vim_free(to);
  4585. #endif
  4586. }
  4587.  
  4588. /*
  4589.  * "indent()" function
  4590.  */
  4591.     static void
  4592. f_indent(argvars, retvar)
  4593.     VAR        argvars;
  4594.     VAR        retvar;
  4595. {
  4596.     linenr_T    lnum;
  4597.  
  4598.     lnum = get_var_lnum(argvars);
  4599.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  4600.     retvar->var_val.var_number = get_indent_lnum(lnum);
  4601.     else
  4602.     retvar->var_val.var_number = -1;
  4603. }
  4604.  
  4605. static int inputsecret_flag = 0;
  4606.  
  4607. /*
  4608.  * "input()" function
  4609.  *     Also handles inputsecret() when inputsecret is set.
  4610.  */
  4611.     static void
  4612. f_input(argvars, retvar)
  4613.     VAR        argvars;
  4614.     VAR        retvar;
  4615. {
  4616.     char_u    *prompt = get_var_string(&argvars[0]);
  4617.     char_u    *p = NULL;
  4618.     int        c;
  4619.     char_u    buf[NUMBUFLEN];
  4620.     int        cmd_silent_save = cmd_silent;
  4621.  
  4622.     retvar->var_type = VAR_STRING;
  4623.  
  4624. #ifdef NO_CONSOLE_INPUT
  4625.     /* While starting up, there is no place to enter text. */
  4626.     if (no_console_input())
  4627.     {
  4628.     retvar->var_val.var_string = NULL;
  4629.     return;
  4630.     }
  4631. #endif
  4632.  
  4633.     cmd_silent = FALSE;        /* Want to see the prompt. */
  4634.     if (prompt != NULL)
  4635.     {
  4636.     /* Only the part of the message after the last NL is considered as
  4637.      * prompt for the command line */
  4638.     p = vim_strrchr(prompt, '\n');
  4639.     if (p == NULL)
  4640.         p = prompt;
  4641.     else
  4642.     {
  4643.         ++p;
  4644.         c = *p;
  4645.         *p = NUL;
  4646.         msg_start();
  4647.         msg_clr_eos();
  4648.         msg_puts_attr(prompt, echo_attr);
  4649.         msg_didout = FALSE;
  4650.         msg_starthere();
  4651.         *p = c;
  4652.     }
  4653.     cmdline_row = msg_row;
  4654.     }
  4655.  
  4656.     if (argvars[1].var_type != VAR_UNKNOWN)
  4657.     stuffReadbuffSpec(get_var_string_buf(&argvars[1], buf));
  4658.  
  4659.     retvar->var_val.var_string =
  4660.         getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr);
  4661.  
  4662.     /* since the user typed this, no need to wait for return */
  4663.     need_wait_return = FALSE;
  4664.     msg_didout = FALSE;
  4665.     cmd_silent = cmd_silent_save;
  4666. }
  4667.  
  4668. /*
  4669.  * "inputdialog()" function
  4670.  */
  4671.     static void
  4672. f_inputdialog(argvars, retvar)
  4673.     VAR        argvars;
  4674.     VAR        retvar;
  4675. {
  4676. #if defined(FEAT_GUI_TEXTDIALOG)
  4677.     if (gui.in_use)
  4678.     {
  4679.     char_u    *message;
  4680.     char_u    buf[NUMBUFLEN];
  4681.  
  4682.     message = get_var_string(&argvars[0]);
  4683.     if (argvars[1].var_type != VAR_UNKNOWN)
  4684.     {
  4685.         STRNCPY(IObuff, get_var_string_buf(&argvars[1], buf), IOSIZE);
  4686.         IObuff[IOSIZE - 1] = NUL;
  4687.     }
  4688.     else
  4689.         IObuff[0] = NUL;
  4690.     if (do_dialog(VIM_QUESTION, NULL, message, (char_u *)_("&OK\n&Cancel"),
  4691.                                   1, IObuff) == 1)
  4692.         retvar->var_val.var_string = vim_strsave(IObuff);
  4693.     else
  4694.         retvar->var_val.var_string = NULL;
  4695.     retvar->var_type = VAR_STRING;
  4696.     }
  4697.     else
  4698. #endif
  4699.     f_input(argvars, retvar);
  4700. }
  4701.  
  4702. /*
  4703.  * "inputsecret()" function
  4704.  */
  4705.     static void
  4706. f_inputsecret(argvars, retvar)
  4707.     VAR        argvars;
  4708.     VAR        retvar;
  4709. {
  4710.     ++cmdline_star;
  4711.     ++inputsecret_flag;
  4712.     f_input(argvars, retvar);
  4713.     --cmdline_star;
  4714.     --inputsecret_flag;
  4715. }
  4716.  
  4717. /*
  4718.  * "isdirectory()" function
  4719.  */
  4720.     static void
  4721. f_isdirectory(argvars, retvar)
  4722.     VAR        argvars;
  4723.     VAR        retvar;
  4724. {
  4725.     retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0]));
  4726. }
  4727.  
  4728. /*
  4729.  * "last_buffer_nr()" function.
  4730.  */
  4731. /*ARGSUSED*/
  4732.     static void
  4733. f_last_buffer_nr(argvars, retvar)
  4734.     VAR        argvars;
  4735.     VAR        retvar;
  4736. {
  4737.     int        n = 0;
  4738.     buf_T    *buf;
  4739.  
  4740.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  4741.     if (n < buf->b_fnum)
  4742.         n = buf->b_fnum;
  4743.  
  4744.     retvar->var_val.var_number = n;
  4745. }
  4746.  
  4747. /*
  4748.  * "line(string)" function
  4749.  */
  4750.     static void
  4751. f_line(argvars, retvar)
  4752.     VAR        argvars;
  4753.     VAR        retvar;
  4754. {
  4755.     linenr_T    lnum = 0;
  4756.     pos_T    *fp;
  4757.  
  4758.     fp = var2fpos(&argvars[0], TRUE);
  4759.     if (fp != NULL)
  4760.     lnum = fp->lnum;
  4761.     retvar->var_val.var_number = lnum;
  4762. }
  4763.  
  4764. /*
  4765.  * "line2byte(lnum)" function
  4766.  */
  4767. /*ARGSUSED*/
  4768.     static void
  4769. f_line2byte(argvars, retvar)
  4770.     VAR        argvars;
  4771.     VAR        retvar;
  4772. {
  4773. #ifndef FEAT_BYTEOFF
  4774.     retvar->var_val.var_number = -1;
  4775. #else
  4776.     linenr_T    lnum;
  4777.  
  4778.     lnum = get_var_lnum(argvars);
  4779.     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
  4780.     retvar->var_val.var_number = -1;
  4781.     else
  4782.     retvar->var_val.var_number = ml_find_line_or_offset(curbuf, lnum, NULL);
  4783.     if (retvar->var_val.var_number >= 0)
  4784.     ++retvar->var_val.var_number;
  4785. #endif
  4786. }
  4787.  
  4788. /*
  4789.  * "lispindent(lnum)" function
  4790.  */
  4791.     static void
  4792. f_lispindent(argvars, retvar)
  4793.     VAR        argvars;
  4794.     VAR        retvar;
  4795. {
  4796. #ifdef FEAT_LISP
  4797.     pos_T    pos;
  4798.     linenr_T    lnum;
  4799.  
  4800.     pos = curwin->w_cursor;
  4801.     lnum = get_var_lnum(argvars);
  4802.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  4803.     {
  4804.     curwin->w_cursor.lnum = lnum;
  4805.     retvar->var_val.var_number = get_lisp_indent();
  4806.     curwin->w_cursor = pos;
  4807.     }
  4808.     else
  4809. #endif
  4810.     retvar->var_val.var_number = -1;
  4811. }
  4812.  
  4813. /*
  4814.  * "localtime()" function
  4815.  */
  4816. /*ARGSUSED*/
  4817.     static void
  4818. f_localtime(argvars, retvar)
  4819.     VAR        argvars;
  4820.     VAR        retvar;
  4821. {
  4822.     retvar->var_val.var_number = (varnumber_T)time(NULL);
  4823. }
  4824.  
  4825. /*
  4826.  * "maparg()" function
  4827.  */
  4828.     static void
  4829. f_maparg(argvars, retvar)
  4830.     VAR        argvars;
  4831.     VAR        retvar;
  4832. {
  4833.     get_maparg(argvars, retvar, TRUE);
  4834. }
  4835.  
  4836. /*
  4837.  * "mapcheck()" function
  4838.  */
  4839.     static void
  4840. f_mapcheck(argvars, retvar)
  4841.     VAR        argvars;
  4842.     VAR        retvar;
  4843. {
  4844.     get_maparg(argvars, retvar, FALSE);
  4845. }
  4846.  
  4847.     static void
  4848. get_maparg(argvars, retvar, exact)
  4849.     VAR        argvars;
  4850.     VAR        retvar;
  4851.     int        exact;
  4852. {
  4853.     char_u    *keys;
  4854.     char_u    *which;
  4855.     char_u    buf[NUMBUFLEN];
  4856.     char_u    *keys_buf = NULL;
  4857.     char_u    *rhs;
  4858.     int        mode;
  4859.     garray_T    ga;
  4860.  
  4861.     /* return empty string for failure */
  4862.     retvar->var_type = VAR_STRING;
  4863.     retvar->var_val.var_string = NULL;
  4864.  
  4865.     keys = get_var_string(&argvars[0]);
  4866.     if (*keys == NUL)
  4867.     return;
  4868.  
  4869.     if (argvars[1].var_type != VAR_UNKNOWN)
  4870.     which = get_var_string_buf(&argvars[1], buf);
  4871.     else
  4872.     which = (char_u *)"";
  4873.     mode = get_map_mode(&which, 0);
  4874.  
  4875.     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE);
  4876.     rhs = check_map(keys, mode, exact);
  4877.     vim_free(keys_buf);
  4878.     if (rhs != NULL)
  4879.     {
  4880.     ga_init(&ga);
  4881.     ga.ga_itemsize = 1;
  4882.     ga.ga_growsize = 40;
  4883.  
  4884.     while (*rhs != NUL)
  4885.         ga_concat(&ga, str2special(&rhs, FALSE));
  4886.  
  4887.     ga_append(&ga, NUL);
  4888.     retvar->var_val.var_string = (char_u *)ga.ga_data;
  4889.     }
  4890. }
  4891.  
  4892. /*
  4893.  * "match()" function
  4894.  */
  4895.     static void
  4896. f_match(argvars, retvar)
  4897.     VAR        argvars;
  4898.     VAR        retvar;
  4899. {
  4900.     find_some_match(argvars, retvar, 1);
  4901. }
  4902.  
  4903. /*
  4904.  * "matchend()" function
  4905.  */
  4906.     static void
  4907. f_matchend(argvars, retvar)
  4908.     VAR        argvars;
  4909.     VAR        retvar;
  4910. {
  4911.     find_some_match(argvars, retvar, 0);
  4912. }
  4913.  
  4914. /*
  4915.  * "matchstr()" function
  4916.  */
  4917.     static void
  4918. f_matchstr(argvars, retvar)
  4919.     VAR        argvars;
  4920.     VAR        retvar;
  4921. {
  4922.     find_some_match(argvars, retvar, 2);
  4923. }
  4924.  
  4925.     static void
  4926. find_some_match(argvars, retvar, type)
  4927.     VAR        argvars;
  4928.     VAR        retvar;
  4929.     int        type;
  4930. {
  4931.     char_u    *str;
  4932.     char_u    *pat;
  4933.     regmatch_T    regmatch;
  4934.     char_u    patbuf[NUMBUFLEN];
  4935.     char_u    *save_cpo;
  4936.     long    start = 0;
  4937.  
  4938.     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
  4939.     save_cpo = p_cpo;
  4940.     p_cpo = (char_u *)"";
  4941.  
  4942.     str = get_var_string(&argvars[0]);
  4943.     pat = get_var_string_buf(&argvars[1], patbuf);
  4944.  
  4945.     if (type == 2)
  4946.     {
  4947.     retvar->var_type = VAR_STRING;
  4948.     retvar->var_val.var_string = NULL;
  4949.     }
  4950.     else
  4951.     retvar->var_val.var_number = -1;
  4952.  
  4953.     if (argvars[2].var_type != VAR_UNKNOWN)
  4954.     {
  4955.     start = get_var_number(&argvars[2]);
  4956.     if (start < 0)
  4957.         start = 0;
  4958.     if (start > (long)STRLEN(str))
  4959.         goto theend;
  4960.     str += start;
  4961.     }
  4962.  
  4963.     regmatch.regprog = vim_regcomp(pat, TRUE);
  4964.     if (regmatch.regprog != NULL)
  4965.     {
  4966.     regmatch.rm_ic = p_ic;
  4967.     if (vim_regexec(®match, str, (colnr_T)0))
  4968.     {
  4969.         if (type == 2)
  4970.         retvar->var_val.var_string = vim_strnsave(regmatch.startp[0],
  4971.                 (int)(regmatch.endp[0] - regmatch.startp[0]));
  4972.         else
  4973.         {
  4974.         if (type != 0)
  4975.             retvar->var_val.var_number = (varnumber_T) (regmatch.startp[0] - str);
  4976.         else
  4977.             retvar->var_val.var_number = (varnumber_T) (regmatch.endp[0] - str);
  4978.         retvar->var_val.var_number += start;
  4979.         }
  4980.     }
  4981.     vim_free(regmatch.regprog);
  4982.     }
  4983.  
  4984. theend:
  4985.     p_cpo = save_cpo;
  4986. }
  4987.  
  4988. /*
  4989.  * "mode()" function
  4990.  */
  4991. /*ARGSUSED*/
  4992.     static void
  4993. f_mode(argvars, retvar)
  4994.     VAR        argvars;
  4995.     VAR        retvar;
  4996. {
  4997.     char_u    buf[2];
  4998.  
  4999. #ifdef FEAT_VISUAL
  5000.     if (VIsual_active)
  5001.     {
  5002.     if (VIsual_select)
  5003.         buf[0] = VIsual_mode + 's' - 'v';
  5004.     else
  5005.         buf[0] = VIsual_mode;
  5006.     }
  5007.     else
  5008. #endif
  5009.     if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
  5010.     buf[0] = 'r';
  5011.     else if (State & INSERT)
  5012.     {
  5013.     if (State & REPLACE_FLAG)
  5014.         buf[0] = 'R';
  5015.     else
  5016.         buf[0] = 'i';
  5017.     }
  5018.     else if (State & CMDLINE)
  5019.     buf[0] = 'c';
  5020.     else
  5021.     buf[0] = 'n';
  5022.  
  5023.     buf[1] = NUL;
  5024.     retvar->var_val.var_string = vim_strsave(buf);
  5025.     retvar->var_type = VAR_STRING;
  5026. }
  5027.  
  5028. /*
  5029.  * "nr2char()" function
  5030.  */
  5031.     static void
  5032. f_nr2char(argvars, retvar)
  5033.     VAR        argvars;
  5034.     VAR        retvar;
  5035. {
  5036.     char_u    buf[2];
  5037.  
  5038.     buf[0] = (char_u)get_var_number(&argvars[0]);
  5039.     retvar->var_type = VAR_STRING;
  5040.     retvar->var_val.var_string = vim_strnsave(buf, 1);
  5041. }
  5042.  
  5043. /*
  5044.  * "rename({from}, {to})" function
  5045.  */
  5046.     static void
  5047. f_rename(argvars, retvar)
  5048.     VAR        argvars;
  5049.     VAR        retvar;
  5050. {
  5051.     char_u    buf[NUMBUFLEN];
  5052.  
  5053.     retvar->var_val.var_number = vim_rename(get_var_string(&argvars[0]),
  5054.                     get_var_string_buf(&argvars[1], buf));
  5055. }
  5056.  
  5057. /*
  5058.  * "resolve()" function
  5059.  */
  5060.     static void
  5061. f_resolve(argvars, retvar)
  5062.     VAR        argvars;
  5063.     VAR        retvar;
  5064. {
  5065.     char_u    *p;
  5066.  
  5067.     p = get_var_string(&argvars[0]);
  5068. #ifdef FEAT_SHORTCUT
  5069.     {
  5070.     char_u    *v = NULL;
  5071.  
  5072.     v = mch_resolve_shortcut(p);
  5073.     if (v != NULL)
  5074.         retvar->var_val.var_string = v;
  5075.     else
  5076.         retvar->var_val.var_string = vim_strsave(p);
  5077.     }
  5078. #else
  5079. # ifdef HAVE_READLINK
  5080.     {
  5081.     char_u    buf[MAXPATHL + 1];
  5082.     char_u    *cpy;
  5083.     int    len;
  5084.  
  5085.     len = readlink((char *)p, (char *)buf, MAXPATHL);
  5086.     if (len > 0)
  5087.     {
  5088.         buf[len] = NUL;
  5089.         if (gettail(p) > p && !mch_isFullName(buf))
  5090.         {
  5091.         /* symlink is relative to directory of argument */
  5092.         cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
  5093.         if (cpy != NULL)
  5094.         {
  5095.             STRCPY(cpy, p);
  5096.             STRCPY(gettail(cpy), buf);
  5097.             retvar->var_val.var_string = cpy;
  5098.             p = NULL;
  5099.         }
  5100.         }
  5101.         else
  5102.         p = buf;
  5103.     }
  5104.     if (p != NULL)
  5105.         retvar->var_val.var_string = vim_strsave(p);
  5106.     }
  5107. # else
  5108.     retvar->var_val.var_string = vim_strsave(p);
  5109. # endif
  5110. #endif
  5111.     retvar->var_type = VAR_STRING;
  5112. }
  5113.  
  5114. /*
  5115.  * "search()" function
  5116.  */
  5117.     static void
  5118. f_search(argvars, retvar)
  5119.     VAR        argvars;
  5120.     VAR        retvar;
  5121. {
  5122.     char_u    *pat;
  5123.     pos_T    pos;
  5124.     int        save_p_ws = p_ws;
  5125.     int        dir;
  5126.  
  5127.     pat = get_var_string(&argvars[0]);
  5128.     dir = get_search_arg(&argvars[1], NULL);    /* may set p_ws */
  5129.  
  5130.     pos = curwin->w_cursor;
  5131.     if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
  5132.                           SEARCH_KEEP, RE_SEARCH) != FAIL)
  5133.     {
  5134.     retvar->var_val.var_number = pos.lnum;
  5135.     curwin->w_cursor = pos;
  5136.     /* "/$" will put the cursor after the end of the line, may need to
  5137.      * correct that here */
  5138.     check_cursor();
  5139.     }
  5140.     else
  5141.     retvar->var_val.var_number = 0;
  5142.     p_ws = save_p_ws;
  5143. }
  5144.  
  5145. #define SP_NOMOVE    1    /* don't move cursor */
  5146. #define SP_REPEAT    2    /* repeat to find outer pair */
  5147. #define SP_RETCOUNT    4    /* return matchcount */
  5148.  
  5149. /*
  5150.  * "searchpair()" function
  5151.  */
  5152.     static void
  5153. f_searchpair(argvars, retvar)
  5154.     VAR        argvars;
  5155.     VAR        retvar;
  5156. {
  5157.     char_u    *spat, *mpat, *epat;
  5158.     char_u    *skip;
  5159.     char_u    *pat, *pat2, *pat3;
  5160.     pos_T    pos;
  5161.     pos_T    firstpos;
  5162.     pos_T    save_cursor;
  5163.     pos_T    save_pos;
  5164.     int        save_p_ws = p_ws;
  5165.     char_u    *save_cpo;
  5166.     int        dir;
  5167.     int        flags = 0;
  5168.     char_u    nbuf1[NUMBUFLEN];
  5169.     char_u    nbuf2[NUMBUFLEN];
  5170.     char_u    nbuf3[NUMBUFLEN];
  5171.     int        n;
  5172.     int        r;
  5173.     int        nest = 1;
  5174.     int        err;
  5175.  
  5176.     retvar->var_val.var_number = 0;    /* default: FAIL */
  5177.  
  5178.     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
  5179.     save_cpo = p_cpo;
  5180.     p_cpo = (char_u *)"";
  5181.  
  5182.     /* Get the three pattern arguments: start, middle, end. */
  5183.     spat = get_var_string(&argvars[0]);
  5184.     mpat = get_var_string_buf(&argvars[1], nbuf1);
  5185.     epat = get_var_string_buf(&argvars[2], nbuf2);
  5186.  
  5187.     /* Make two search patterns: start/end (pat2, for in nested pairs) and
  5188.      * start/middle/end (pat3, for the top pair). */
  5189.     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
  5190.     pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
  5191.     if (pat2 == NULL || pat3 == NULL)
  5192.     goto theend;
  5193.     sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
  5194.     if (*mpat == NUL)
  5195.     STRCPY(pat3, pat2);
  5196.     else
  5197.     sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
  5198.                                 spat, epat, mpat);
  5199.  
  5200.     /* Handle the optional fourth argument: flags */
  5201.     dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
  5202.  
  5203.     /* Optional fifth argument: skip expresion */
  5204.     if (argvars[4].var_type == VAR_UNKNOWN)
  5205.     skip = (char_u *)"";
  5206.     else
  5207.     skip = get_var_string_buf(&argvars[4], nbuf3);
  5208.  
  5209.     save_cursor = curwin->w_cursor;
  5210.     pos = curwin->w_cursor;
  5211.     firstpos.lnum = 0;
  5212.     pat = pat3;
  5213.     for (;;)
  5214.     {
  5215.     n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
  5216.                               SEARCH_KEEP, RE_SEARCH);
  5217.     if (n == FAIL || (firstpos.lnum != 0 && equal(pos, firstpos)))
  5218.         /* didn't find it or found the first match again: FAIL */
  5219.         break;
  5220.  
  5221.     if (firstpos.lnum == 0)
  5222.         firstpos = pos;
  5223.  
  5224.     /* If the skip pattern matches, ignore this match. */
  5225.     if (*skip != NUL)
  5226.     {
  5227.         save_pos = curwin->w_cursor;
  5228.         curwin->w_cursor = pos;
  5229.         r = eval_to_bool(skip, &err, NULL, FALSE);
  5230.         curwin->w_cursor = save_pos;
  5231.         if (err)
  5232.         {
  5233.         /* Evaluating {skip} caused an error, break here. */
  5234.         curwin->w_cursor = save_cursor;
  5235.         retvar->var_val.var_number = -1;
  5236.         break;
  5237.         }
  5238.         if (r)
  5239.         continue;
  5240.     }
  5241.  
  5242.     if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
  5243.     {
  5244.         /* Found end when searching backwards or start when searching
  5245.          * forward: nested pair. */
  5246.         ++nest;
  5247.         pat = pat2;        /* nested, don't search for middle */
  5248.     }
  5249.     else
  5250.     {
  5251.         /* Found end when searching forward or start when searching
  5252.          * backward: end of (nested) pair; or found middle in outer pair. */
  5253.         if (--nest == 1)
  5254.         pat = pat3;    /* outer level, search for middle */
  5255.     }
  5256.  
  5257.     if (nest == 0)
  5258.     {
  5259.         /* Found the match: return matchcount or line number. */
  5260.         if (flags & SP_RETCOUNT)
  5261.         ++retvar->var_val.var_number;
  5262.         else
  5263.         retvar->var_val.var_number = pos.lnum;
  5264.         curwin->w_cursor = pos;
  5265.         if (!(flags & SP_REPEAT))
  5266.         break;
  5267.         nest = 1;        /* search for next unmatched */
  5268.     }
  5269.     }
  5270.  
  5271.     /* If 'n' flag is used or search failed: restore cursor position. */
  5272.     if ((flags & SP_NOMOVE) || retvar->var_val.var_number == 0)
  5273.     curwin->w_cursor = save_cursor;
  5274.  
  5275. theend:
  5276.     vim_free(pat2);
  5277.     vim_free(pat3);
  5278.     p_ws = save_p_ws;
  5279.     p_cpo = save_cpo;
  5280. }
  5281.  
  5282.     static int
  5283. get_search_arg(varp, flagsp)
  5284.     VAR        varp;
  5285.     int        *flagsp;
  5286. {
  5287.     int        dir = FORWARD;
  5288.     char_u    *flags;
  5289.     char_u    nbuf[NUMBUFLEN];
  5290.  
  5291.     if (varp->var_type != VAR_UNKNOWN)
  5292.     {
  5293.     flags = get_var_string_buf(varp, nbuf);
  5294.     if (vim_strchr(flags, 'b') != NULL)
  5295.         dir = BACKWARD;
  5296.     if (vim_strchr(flags, 'w') != NULL)
  5297.         p_ws = TRUE;
  5298.     if (vim_strchr(flags, 'W') != NULL)
  5299.         p_ws = FALSE;
  5300.     if (flagsp != NULL)
  5301.     {
  5302.         if (vim_strchr(flags, 'n') != NULL)
  5303.         *flagsp |= SP_NOMOVE;
  5304.         if (vim_strchr(flags, 'r') != NULL)
  5305.         *flagsp |= SP_REPEAT;
  5306.         if (vim_strchr(flags, 'm') != NULL)
  5307.         *flagsp |= SP_RETCOUNT;
  5308.     }
  5309.     }
  5310.     return dir;
  5311. }
  5312.  
  5313. /*
  5314.  * "setbufvar()" function
  5315.  */
  5316. /*ARGSUSED*/
  5317.     static void
  5318. f_setbufvar(argvars, retvar)
  5319.     VAR        argvars;
  5320.     VAR        retvar;
  5321. {
  5322.     buf_T    *buf;
  5323. #ifdef FEAT_AUTOCMD
  5324.     aco_save_T    aco;
  5325. #else
  5326.     buf_T    *save_curbuf;
  5327. #endif
  5328.     char_u    *varname, *bufvarname;
  5329.     VAR        varp;
  5330.     char_u    nbuf[NUMBUFLEN];
  5331.  
  5332.     ++emsg_off;
  5333.     buf = get_buf_var(&argvars[0]);
  5334.     varname = get_var_string(&argvars[1]);
  5335.     varp = &argvars[2];
  5336.  
  5337.     if (buf != NULL && varname != NULL && varp != NULL)
  5338.     {
  5339.     /* set curbuf to be our buf, temporarily */
  5340. #ifdef FEAT_AUTOCMD
  5341.     aucmd_prepbuf(&aco, buf);
  5342. #else
  5343.     save_curbuf = curbuf;
  5344.     curbuf = buf;
  5345. #endif
  5346.  
  5347.     if (*varname == '&')
  5348.     {
  5349.         ++varname;
  5350.         set_option_value(varname, get_var_number(varp),
  5351.                    get_var_string_buf(varp, nbuf), OPT_LOCAL);
  5352.     }
  5353.     else
  5354.     {
  5355.         bufvarname = alloc((unsigned)STRLEN(varname) + 3);
  5356.         if (bufvarname != NULL)
  5357.         {
  5358.         STRCPY(bufvarname, "b:");
  5359.         STRCPY(bufvarname + 2, varname);
  5360.         set_var(bufvarname, varp);
  5361.         vim_free(bufvarname);
  5362.         }
  5363.     }
  5364.  
  5365.     /* reset notion of buffer */
  5366. #ifdef FEAT_AUTOCMD
  5367.     aucmd_restbuf(&aco);
  5368. #else
  5369.     curbuf = save_curbuf;
  5370. #endif
  5371.     }
  5372.     --emsg_off;
  5373. }
  5374.  
  5375. /*
  5376.  * "setline()" function
  5377.  */
  5378.     static void
  5379. f_setline(argvars, retvar)
  5380.     VAR        argvars;
  5381.     VAR        retvar;
  5382. {
  5383.     linenr_T    lnum;
  5384.     char_u    *line;
  5385.  
  5386.     lnum = get_var_lnum(argvars);
  5387.     line = get_var_string(&argvars[1]);
  5388.     retvar->var_val.var_number = 1;        /* FAIL is default */
  5389.  
  5390.     if (lnum >= 1
  5391.         && lnum <= curbuf->b_ml.ml_line_count
  5392.         && u_savesub(lnum) == OK
  5393.         && ml_replace(lnum, line, TRUE) == OK)
  5394.     {
  5395.     changed_bytes(lnum, 0);
  5396.     check_cursor_col();
  5397.     retvar->var_val.var_number = 0;
  5398.     }
  5399. }
  5400.  
  5401. /*
  5402.  * "setwinvar(expr)" function
  5403.  */
  5404. /*ARGSUSED*/
  5405.     static void
  5406. f_setwinvar(argvars, retvar)
  5407.     VAR        argvars;
  5408.     VAR        retvar;
  5409. {
  5410.     win_T    *win;
  5411. #ifdef FEAT_WINDOWS
  5412.     win_T    *save_curwin;
  5413. #endif
  5414.     char_u    *varname, *winvarname;
  5415.     VAR        varp;
  5416.     char_u    nbuf[NUMBUFLEN];
  5417.  
  5418.     ++emsg_off;
  5419.     win = find_win_by_nr(&argvars[0]);
  5420.     varname = get_var_string(&argvars[1]);
  5421.     varp = &argvars[2];
  5422.  
  5423.     if (win != NULL && varname != NULL && varp != NULL)
  5424.     {
  5425. #ifdef FEAT_WINDOWS
  5426.     /* set curwin to be our win, temporarily */
  5427.     save_curwin = curwin;
  5428.     curwin = win;
  5429.     curbuf = curwin->w_buffer;
  5430. #endif
  5431.  
  5432.     if (*varname == '&')
  5433.     {
  5434.         ++varname;
  5435.         set_option_value(varname, get_var_number(varp),
  5436.                    get_var_string_buf(varp, nbuf), OPT_LOCAL);
  5437.     }
  5438.     else
  5439.     {
  5440.         winvarname = alloc((unsigned)STRLEN(varname) + 3);
  5441.         if (winvarname != NULL)
  5442.         {
  5443.         STRCPY(winvarname, "w:");
  5444.         STRCPY(winvarname + 2, varname);
  5445.         set_var(winvarname, varp);
  5446.         vim_free(winvarname);
  5447.         }
  5448.     }
  5449.  
  5450. #ifdef FEAT_WINDOWS
  5451.     /* Restore current window, if it's still valid (autocomands can make
  5452.      * it invalid). */
  5453.     if (win_valid(save_curwin))
  5454.     {
  5455.         curwin = save_curwin;
  5456.         curbuf = curwin->w_buffer;
  5457.     }
  5458. #endif
  5459.     }
  5460.     --emsg_off;
  5461. }
  5462.  
  5463. /*
  5464.  * "nextnonblank()" function
  5465.  */
  5466.     static void
  5467. f_nextnonblank(argvars, retvar)
  5468.     VAR        argvars;
  5469.     VAR        retvar;
  5470. {
  5471.     linenr_T    lnum;
  5472.  
  5473.     for (lnum = get_var_lnum(argvars); ; ++lnum)
  5474.     {
  5475.     if (lnum > curbuf->b_ml.ml_line_count)
  5476.     {
  5477.         lnum = 0;
  5478.         break;
  5479.     }
  5480.     if (*skipwhite(ml_get(lnum)) != NUL)
  5481.         break;
  5482.     }
  5483.     retvar->var_val.var_number = lnum;
  5484. }
  5485.  
  5486. /*
  5487.  * "prevnonblank()" function
  5488.  */
  5489.     static void
  5490. f_prevnonblank(argvars, retvar)
  5491.     VAR        argvars;
  5492.     VAR        retvar;
  5493. {
  5494.     linenr_T    lnum;
  5495.  
  5496.     lnum = get_var_lnum(argvars);
  5497.     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
  5498.     lnum = 0;
  5499.     else
  5500.     while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
  5501.         --lnum;
  5502.     retvar->var_val.var_number = lnum;
  5503. }
  5504.  
  5505. #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
  5506. static int check_connection __ARGS((void));
  5507.  
  5508.     static int
  5509. check_connection()
  5510. {
  5511.     if (X_DISPLAY == NULL)
  5512.     {
  5513.     EMSG(_("E240: No connection to Vim server"));
  5514.     return FAIL;
  5515.     }
  5516.     return OK;
  5517. }
  5518. #endif
  5519.  
  5520. /*ARGSUSED*/
  5521.     static void
  5522. f_serverlist(argvars, retvar)
  5523.     VAR        argvars;
  5524.     VAR        retvar;
  5525. {
  5526.     char_u    *r = NULL;
  5527.  
  5528. #ifdef FEAT_CLIENTSERVER
  5529. # ifdef WIN32
  5530.     r = serverGetVimNames();
  5531. # else
  5532.     if (check_connection() == OK)
  5533.     r = serverGetVimNames(X_DISPLAY);
  5534. # endif
  5535. #endif
  5536.     retvar->var_type = VAR_STRING;
  5537.     retvar->var_val.var_string = r;
  5538. }
  5539.  
  5540. /*ARGSUSED*/
  5541.     static void
  5542. f_remote_peek(argvars, retvar)
  5543.     VAR        argvars;
  5544.     VAR        retvar;
  5545. {
  5546. #ifdef FEAT_CLIENTSERVER
  5547.     var        v;
  5548.     char_u    *s;
  5549.  
  5550. # ifdef WIN32
  5551.     int        n = 0;
  5552.  
  5553.     sscanf(get_var_string(&argvars[0]), "%x", &n);
  5554.     if (n == 0)
  5555.     retvar->var_val.var_number = -1;
  5556.     else
  5557.     {
  5558.     s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
  5559.     retvar->var_val.var_number = (s != NULL);
  5560.     }
  5561. # else
  5562.     retvar->var_val.var_number = 0;
  5563.     if (!check_connection())
  5564.     return;
  5565.  
  5566.     retvar->var_val.var_number = serverPeekReply(X_DISPLAY,
  5567.                  serverStrToWin(get_var_string(&argvars[0])), &s);
  5568. # endif
  5569.  
  5570.     if (argvars[1].var_type != VAR_UNKNOWN && retvar->var_val.var_number > 0)
  5571.     {
  5572.     v.var_type = VAR_STRING;
  5573.     v.var_val.var_string = vim_strsave(s);
  5574.     set_var(get_var_string(&argvars[1]), &v);
  5575.     }
  5576. #else
  5577.     retvar->var_val.var_number = -1;
  5578. #endif
  5579. }
  5580.  
  5581. /*ARGSUSED*/
  5582.     static void
  5583. f_remote_read(argvars, retvar)
  5584.     VAR        argvars;
  5585.     VAR        retvar;
  5586. {
  5587.     char_u    *r = NULL;
  5588.  
  5589. #ifdef FEAT_CLIENTSERVER
  5590. # ifdef WIN32
  5591.     /* The server's HWND is encoded in the 'id' parameter */
  5592.     int        n = 0;
  5593.  
  5594.     sscanf(get_var_string(&argvars[0]), "%x", &n);
  5595.     if (n != 0)
  5596.     r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
  5597.     if (r == NULL)
  5598. # else
  5599.     if (check_connection() == FAIL
  5600.         || serverReadReply(X_DISPLAY,
  5601.           serverStrToWin(get_var_string(&argvars[0])), &r, FALSE) < 0)
  5602. # endif
  5603.     EMSG(_("E277: Unable to read a server reply"));
  5604. #endif
  5605.     retvar->var_type = VAR_STRING;
  5606.     retvar->var_val.var_string = r;
  5607. }
  5608.  
  5609. /*ARGSUSED*/
  5610.     static void
  5611. f_server2client(argvars, retvar)
  5612.     VAR        argvars;
  5613.     VAR        retvar;
  5614. {
  5615. #ifdef FEAT_CLIENTSERVER
  5616.     char_u    buf[NUMBUFLEN];
  5617.     char_u    *server = get_var_string(&argvars[0]);
  5618.     char_u    *reply = get_var_string_buf(&argvars[1], buf);
  5619.  
  5620.     retvar->var_val.var_number = -1;
  5621. # ifndef WIN32
  5622.     if (!check_connection())
  5623.     return;
  5624. # endif
  5625.  
  5626.     if (serverSendReply(server, reply) < 0)
  5627.     {
  5628.     EMSG(_("E258: Unable to send to client"));
  5629.     return;
  5630.     }
  5631.     retvar->var_val.var_number = 0;
  5632. #else
  5633.     retvar->var_val.var_number = -1;
  5634. #endif
  5635. }
  5636.  
  5637. #ifdef FEAT_CLIENTSERVER
  5638. static void remote_common __ARGS((VAR argvars, VAR retvar, int expr));
  5639.  
  5640.     static void
  5641. remote_common(argvars, retvar, expr)
  5642.     VAR        argvars;
  5643.     VAR        retvar;
  5644.     int        expr;
  5645. {
  5646.     char_u    *server_name;
  5647.     char_u    *keys;
  5648.     char_u    *r = NULL;
  5649.     char_u    buf[NUMBUFLEN];
  5650. # ifdef WIN32
  5651.     HWND    w;
  5652. # else
  5653.     Window    w;
  5654. # endif
  5655.  
  5656. # ifdef FEAT_X11
  5657.     if (!check_connection())
  5658.     return;
  5659. # endif
  5660.  
  5661.     server_name = get_var_string(&argvars[0]);
  5662.     keys = get_var_string_buf(&argvars[1], buf);
  5663. # ifdef WIN32
  5664.     if (serverSendToVim(server_name, keys, &r, &w, expr) < 0)
  5665. # else
  5666.     if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0) < 0)
  5667. # endif
  5668.     {
  5669.     EMSG2(_("E241: Unable to send to %s"), server_name);
  5670.     return;
  5671.     }
  5672.  
  5673.     retvar->var_val.var_string = r;
  5674.  
  5675.     if (argvars[2].var_type != VAR_UNKNOWN)
  5676.     {
  5677.     var    v;
  5678.     char_u    str[30];
  5679.  
  5680.     sprintf((char *)str, "0x%x", (unsigned int)w);
  5681.     v.var_type = VAR_STRING;
  5682.     v.var_val.var_string = vim_strsave(str);
  5683.     set_var(get_var_string(&argvars[2]), &v);
  5684.     }
  5685. }
  5686. #endif
  5687.  
  5688. /*
  5689.  * "remote_expr()" function
  5690.  */
  5691. /*ARGSUSED*/
  5692.     static void
  5693. f_remote_expr(argvars, retvar)
  5694.     VAR        argvars;
  5695.     VAR        retvar;
  5696. {
  5697.     retvar->var_type = VAR_STRING;
  5698.     retvar->var_val.var_string = NULL;
  5699. #ifdef FEAT_CLIENTSERVER
  5700.     remote_common(argvars, retvar, TRUE);
  5701. #endif
  5702. }
  5703.  
  5704. /*
  5705.  * "remote_send()" function
  5706.  */
  5707. /*ARGSUSED*/
  5708.     static void
  5709. f_remote_send(argvars, retvar)
  5710.     VAR        argvars;
  5711.     VAR        retvar;
  5712. {
  5713.     retvar->var_type = VAR_STRING;
  5714.     retvar->var_val.var_string = NULL;
  5715. #ifdef FEAT_CLIENTSERVER
  5716.     remote_common(argvars, retvar, FALSE);
  5717. #endif
  5718. }
  5719.  
  5720. /*
  5721.  * "remote_foreground()" function
  5722.  */
  5723. /*ARGSUSED*/
  5724.     static void
  5725. f_remote_foreground(argvars, retvar)
  5726.     VAR        argvars;
  5727.     VAR        retvar;
  5728. {
  5729.     retvar->var_val.var_number = 0;
  5730. #ifdef FEAT_CLIENTSERVER
  5731. # ifdef WIN32
  5732.     /* On Win32 it's done in this application. */
  5733.     serverForeground(get_var_string(&argvars[0]));
  5734. # else
  5735.     /* Send a foreground() expression to the server. */
  5736.     argvars[1].var_type = VAR_STRING;
  5737.     argvars[1].var_val.var_string = vim_strsave((char_u *)"foreground()");
  5738.     argvars[2].var_type = VAR_UNKNOWN;
  5739.     remote_common(argvars, retvar, TRUE);
  5740.     vim_free(argvars[1].var_val.var_string);
  5741. # endif
  5742. #endif
  5743. }
  5744.  
  5745. #ifdef HAVE_STRFTIME
  5746. /*
  5747.  * "strftime({format}[, {time}])" function
  5748.  */
  5749.     static void
  5750. f_strftime(argvars, retvar)
  5751.     VAR        argvars;
  5752.     VAR        retvar;
  5753. {
  5754.     char_u    result_buf[80];
  5755.     struct tm    *curtime;
  5756.     time_t    seconds;
  5757.     char_u    *p;
  5758.  
  5759.     p = get_var_string(&argvars[0]);
  5760.     if (argvars[1].var_type == VAR_UNKNOWN)
  5761.     seconds = time(NULL);
  5762.     else
  5763.     seconds = (time_t)get_var_number(&argvars[1]);
  5764.     curtime = localtime(&seconds);
  5765.     /* MSVC returns NULL for an invalid value of seconds. */
  5766.     if (curtime == NULL)
  5767.     STRCPY(result_buf, _("(Invalid)"));
  5768.     else
  5769.     (void)strftime((char *)result_buf, (size_t)80, (char *)p, curtime);
  5770.  
  5771.     retvar->var_type = VAR_STRING;
  5772.     retvar->var_val.var_string = vim_strsave(result_buf);
  5773. }
  5774. #endif
  5775.  
  5776. /*
  5777.  * "stridx()" function
  5778.  */
  5779.     static void
  5780. f_stridx(argvars, retvar)
  5781.     VAR        argvars;
  5782.     VAR        retvar;
  5783. {
  5784.     char_u    buf[NUMBUFLEN];
  5785.     char_u    *needle;
  5786.     char_u    *haystack;
  5787.     char_u    *pos;
  5788.  
  5789.     needle = get_var_string(&argvars[1]);
  5790.     haystack = get_var_string_buf(&argvars[0], buf);
  5791.     pos    = (char_u *)strstr((char *)haystack, (char *)needle);
  5792.  
  5793.     if (pos == NULL)
  5794.     retvar->var_val.var_number = -1;
  5795.     else
  5796.     retvar->var_val.var_number = (varnumber_T) (pos - haystack);
  5797. }
  5798.  
  5799. /*
  5800.  * "strridx()" function
  5801.  */
  5802.     static void
  5803. f_strridx(argvars, retvar)
  5804.     VAR        argvars;
  5805.     VAR        retvar;
  5806. {
  5807.     char_u    buf[NUMBUFLEN];
  5808.     char_u    *needle;
  5809.     char_u    *haystack;
  5810.     char_u    *rest;
  5811.     char_u    *lastmatch = NULL;
  5812.  
  5813.     needle = get_var_string(&argvars[1]);
  5814.     haystack = get_var_string_buf(&argvars[0], buf);
  5815.     rest = haystack;
  5816.     while (*haystack != '\0')
  5817.     {
  5818.     rest = (char_u *)strstr((char *)rest, (char *)needle);
  5819.     if (rest == NULL)
  5820.         break;
  5821.     lastmatch = rest++;
  5822.     }
  5823.  
  5824.     if (lastmatch == NULL)
  5825.     retvar->var_val.var_number = -1;
  5826.     else
  5827.     retvar->var_val.var_number = (varnumber_T) (lastmatch - haystack);
  5828. }
  5829.  
  5830. /*
  5831.  * "strlen()" function
  5832.  */
  5833.     static void
  5834. f_strlen(argvars, retvar)
  5835.     VAR        argvars;
  5836.     VAR        retvar;
  5837. {
  5838.     retvar->var_val.var_number = (varnumber_T) (STRLEN(get_var_string(&argvars[0])));
  5839. }
  5840.  
  5841. /*
  5842.  * "strpart()" function
  5843.  */
  5844.     static void
  5845. f_strpart(argvars, retvar)
  5846.     VAR        argvars;
  5847.     VAR        retvar;
  5848. {
  5849.     char_u    *p;
  5850.     int        n;
  5851.     int        len;
  5852.     int        slen;
  5853.  
  5854.     p = get_var_string(&argvars[0]);
  5855.     n = get_var_number(&argvars[1]);
  5856.     if (argvars[2].var_type != VAR_UNKNOWN)
  5857.     len = get_var_number(&argvars[2]);
  5858.     else
  5859.     len = (int)STRLEN(p) - n;
  5860.  
  5861.     slen = (int)STRLEN(p);
  5862.     /*
  5863.      * Only return the overlap between the specified part and the actual
  5864.      * string.
  5865.      */
  5866.     if (n < 0)
  5867.     {
  5868.     len += n;
  5869.     n = 0;
  5870.     }
  5871.     else if (n > slen)
  5872.     n = slen;
  5873.     if (len < 0)
  5874.     len = 0;
  5875.     else if (n + len > slen)
  5876.     len = slen - n;
  5877.  
  5878.     retvar->var_type = VAR_STRING;
  5879.     retvar->var_val.var_string = vim_strnsave(p + n, len);
  5880. }
  5881.  
  5882. /*
  5883.  * "strtrans()" function
  5884.  */
  5885.     static void
  5886. f_strtrans(argvars, retvar)
  5887.     VAR        argvars;
  5888.     VAR        retvar;
  5889. {
  5890.     retvar->var_type = VAR_STRING;
  5891.     retvar->var_val.var_string = transstr(get_var_string(&argvars[0]));
  5892. }
  5893.  
  5894. /*
  5895.  * "synID(line, col, trans)" function
  5896.  */
  5897. /*ARGSUSED*/
  5898.     static void
  5899. f_synID(argvars, retvar)
  5900.     VAR        argvars;
  5901.     VAR        retvar;
  5902. {
  5903.     int        id = 0;
  5904. #ifdef FEAT_SYN_HL
  5905.     long    line;
  5906.     long    col;
  5907.     int        trans;
  5908.  
  5909.     line = get_var_lnum(argvars);
  5910.     col = get_var_number(&argvars[1]) - 1;
  5911.     trans = get_var_number(&argvars[2]);
  5912.  
  5913.     if (line >= 1 && line <= curbuf->b_ml.ml_line_count
  5914.         && col >= 0 && col < (long)STRLEN(ml_get(line)))
  5915.     id = syn_get_id(line, col, trans);
  5916. #endif
  5917.  
  5918.     retvar->var_val.var_number = id;
  5919. }
  5920.  
  5921. /*
  5922.  * "synIDattr(id, what [, mode])" function
  5923.  */
  5924. /*ARGSUSED*/
  5925.     static void
  5926. f_synIDattr(argvars, retvar)
  5927.     VAR        argvars;
  5928.     VAR        retvar;
  5929. {
  5930.     char_u    *p = NULL;
  5931. #ifdef FEAT_SYN_HL
  5932.     int        id;
  5933.     char_u    *what;
  5934.     char_u    *mode;
  5935.     char_u    modebuf[NUMBUFLEN];
  5936.     int        modec;
  5937.  
  5938.     id = get_var_number(&argvars[0]);
  5939.     what = get_var_string(&argvars[1]);
  5940.     if (argvars[2].var_type != VAR_UNKNOWN)
  5941.     {
  5942.     mode = get_var_string_buf(&argvars[2], modebuf);
  5943.     modec = TO_LOWER(mode[0]);
  5944.     if (modec != 't' && modec != 'c'
  5945. #ifdef FEAT_GUI
  5946.         && modec != 'g'
  5947. #endif
  5948.         )
  5949.         modec = 0;    /* replace invalid with current */
  5950.     }
  5951.     else
  5952.     {
  5953. #ifdef FEAT_GUI
  5954.     if (gui.in_use)
  5955.         modec = 'g';
  5956.     else
  5957. #endif
  5958.         if (t_colors > 1)
  5959.         modec = 'c';
  5960.     else
  5961.         modec = 't';
  5962.     }
  5963.  
  5964.  
  5965.     switch (TO_LOWER(what[0]))
  5966.     {
  5967.     case 'b':
  5968.         if (TO_LOWER(what[1]) == 'g')        /* bg[#] */
  5969.             p = highlight_color(id, what, modec);
  5970.         else                    /* bold */
  5971.             p = highlight_has_attr(id, HL_BOLD, modec);
  5972.         break;
  5973.  
  5974.     case 'f':                    /* fg[#] */
  5975.         p = highlight_color(id, what, modec);
  5976.         break;
  5977.  
  5978.     case 'i':
  5979.         if (TO_LOWER(what[1]) == 'n')        /* inverse */
  5980.             p = highlight_has_attr(id, HL_INVERSE, modec);
  5981.         else                    /* italic */
  5982.             p = highlight_has_attr(id, HL_ITALIC, modec);
  5983.         break;
  5984.  
  5985.     case 'n':                    /* name */
  5986.         p = get_highlight_name(NULL, id - 1);
  5987.         break;
  5988.  
  5989.     case 'r':                    /* reverse */
  5990.         p = highlight_has_attr(id, HL_INVERSE, modec);
  5991.         break;
  5992.  
  5993.     case 's':                    /* standout */
  5994.         p = highlight_has_attr(id, HL_STANDOUT, modec);
  5995.         break;
  5996.  
  5997.     case 'u':                    /* underline */
  5998.         p = highlight_has_attr(id, HL_UNDERLINE, modec);
  5999.         break;
  6000.     }
  6001.  
  6002.     if (p != NULL)
  6003.     p = vim_strsave(p);
  6004. #endif
  6005.     retvar->var_type = VAR_STRING;
  6006.     retvar->var_val.var_string = p;
  6007. }
  6008.  
  6009. /*
  6010.  * "synIDtrans(id)" function
  6011.  */
  6012. /*ARGSUSED*/
  6013.     static void
  6014. f_synIDtrans(argvars, retvar)
  6015.     VAR        argvars;
  6016.     VAR        retvar;
  6017. {
  6018.     int        id;
  6019.  
  6020. #ifdef FEAT_SYN_HL
  6021.     id = get_var_number(&argvars[0]);
  6022.  
  6023.     if (id > 0)
  6024.     id = syn_get_final_id(id);
  6025.     else
  6026. #endif
  6027.     id = 0;
  6028.  
  6029.     retvar->var_val.var_number = id;
  6030. }
  6031.  
  6032. /*
  6033.  * "system()" function
  6034.  */
  6035.     static void
  6036. f_system(argvars, retvar)
  6037.     VAR        argvars;
  6038.     VAR        retvar;
  6039. {
  6040.     char_u    *p;
  6041.  
  6042.     p = get_cmd_output(get_var_string(&argvars[0]), SHELL_SILENT);
  6043. #ifdef USE_CR
  6044.     /* translate <CR> into <NL> */
  6045.     if (p != NULL)
  6046.     {
  6047.     char_u    *s;
  6048.  
  6049.     for (s = p; *s; ++s)
  6050.     {
  6051.         if (*s == CR)
  6052.         *s = NL;
  6053.     }
  6054.     }
  6055. #else
  6056. # ifdef USE_CRNL
  6057.     /* translate <CR><NL> into <NL> */
  6058.     if (p != NULL)
  6059.     {
  6060.     char_u    *s, *d;
  6061.  
  6062.     d = p;
  6063.     for (s = p; *s; ++s)
  6064.     {
  6065.         if (s[0] == CR && s[1] == NL)
  6066.         ++s;
  6067.         *d++ = *s;
  6068.     }
  6069.     *d = NUL;
  6070.     }
  6071. # endif
  6072. #endif
  6073.     retvar->var_type = VAR_STRING;
  6074.     retvar->var_val.var_string = p;
  6075. }
  6076.  
  6077. /*
  6078.  * "submatch()" function
  6079.  */
  6080.     static void
  6081. f_submatch(argvars, retvar)
  6082.     VAR        argvars;
  6083.     VAR        retvar;
  6084. {
  6085.     retvar->var_type = VAR_STRING;
  6086.     retvar->var_val.var_string = reg_submatch((int)get_var_number(&argvars[0]));
  6087. }
  6088.  
  6089. /*
  6090.  * "substitute()" function
  6091.  */
  6092.     static void
  6093. f_substitute(argvars, retvar)
  6094.     VAR        argvars;
  6095.     VAR        retvar;
  6096. {
  6097.     char_u    patbuf[NUMBUFLEN];
  6098.     char_u    subbuf[NUMBUFLEN];
  6099.     char_u    flagsbuf[NUMBUFLEN];
  6100.  
  6101.     retvar->var_type = VAR_STRING;
  6102.     retvar->var_val.var_string = do_string_sub(
  6103.         get_var_string(&argvars[0]),
  6104.         get_var_string_buf(&argvars[1], patbuf),
  6105.         get_var_string_buf(&argvars[2], subbuf),
  6106.         get_var_string_buf(&argvars[3], flagsbuf));
  6107. }
  6108.  
  6109. /*
  6110.  * "tempname()" function
  6111.  */
  6112. /*ARGSUSED*/
  6113.     static void
  6114. f_tempname(argvars, retvar)
  6115.     VAR        argvars;
  6116.     VAR        retvar;
  6117. {
  6118.     static int    x = 'A';
  6119.  
  6120.     retvar->var_type = VAR_STRING;
  6121.     retvar->var_val.var_string = vim_tempname(x);
  6122.     /* advance 'x', so that there are at least 26 different names */
  6123.     if (x == 'Z')
  6124.     x = 'A';
  6125.     else
  6126.     {
  6127. #ifdef EBCDIC
  6128.     if (x == 'I')
  6129.         x = 'J';
  6130.     else if (x == 'R')
  6131.         x = 'S';
  6132.     else
  6133. #endif
  6134.         ++x;
  6135.     }
  6136. }
  6137.  
  6138. /*
  6139.  * "tolower(string)" function
  6140.  */
  6141.     static void
  6142. f_tolower(argvars, retvar)
  6143.     VAR        argvars;
  6144.     VAR        retvar;
  6145. {
  6146.     char_u    *p;
  6147.  
  6148.     p = vim_strsave(get_var_string(&argvars[0]));
  6149.     retvar->var_type = VAR_STRING;
  6150.     retvar->var_val.var_string = p;
  6151.  
  6152.     if (p != NULL)
  6153.     while (*p != NUL)
  6154.     {
  6155. #ifdef FEAT_MBYTE
  6156.         if (enc_utf8)
  6157.         {
  6158.         int c, lc, l;
  6159.  
  6160.         c = utf_ptr2char(p);
  6161.         lc = utf_tolower(c);
  6162.         l = utf_ptr2len_check(p);
  6163.         /* TODO: reallocate string when byte count changes. */
  6164.         if (utf_char2len(lc) == l)
  6165.             utf_char2bytes(lc, p);
  6166.         p += l;
  6167.         }
  6168.         else
  6169. #endif
  6170.         {
  6171.         *p = TO_LOWER(*p); /* note that tolower() can be a macro */
  6172.         ++p;
  6173.         }
  6174.     }
  6175. }
  6176.  
  6177. /*
  6178.  * "toupper(string)" function
  6179.  */
  6180.     static void
  6181. f_toupper(argvars, retvar)
  6182.     VAR        argvars;
  6183.     VAR        retvar;
  6184. {
  6185.     char_u    *p;
  6186.  
  6187.     p = vim_strsave(get_var_string(&argvars[0]));
  6188.     retvar->var_type = VAR_STRING;
  6189.     retvar->var_val.var_string = p;
  6190.  
  6191.     if (p != NULL)
  6192.     while (*p != NUL)
  6193.     {
  6194. #ifdef FEAT_MBYTE
  6195.         if (enc_utf8)
  6196.         {
  6197.         int c, uc, l;
  6198.  
  6199.         c = utf_ptr2char(p);
  6200.         uc = utf_toupper(c);
  6201.         l = utf_ptr2len_check(p);
  6202.         /* TODO: reallocate string when byte count changes. */
  6203.         if (utf_char2len(uc) == l)
  6204.             utf_char2bytes(uc, p);
  6205.         p += l;
  6206.         }
  6207.         else
  6208. #endif
  6209.         {
  6210.         *p = TO_UPPER(*p); /* note that toupper() can be a macro */
  6211.         p++;
  6212.         }
  6213.     }
  6214. }
  6215.  
  6216. /*
  6217.  * "type(expr)" function
  6218.  */
  6219.     static void
  6220. f_type(argvars, retvar)
  6221.     VAR        argvars;
  6222.     VAR        retvar;
  6223. {
  6224.     if (argvars[0].var_type == VAR_NUMBER)
  6225.     retvar->var_val.var_number = 0;
  6226.     else
  6227.     retvar->var_val.var_number = 1;
  6228. }
  6229.  
  6230. /*
  6231.  * "virtcol(string)" function
  6232.  */
  6233.     static void
  6234. f_virtcol(argvars, retvar)
  6235.     VAR        argvars;
  6236.     VAR        retvar;
  6237. {
  6238.     colnr_T    vcol = 0;
  6239.     pos_T    *fp;
  6240.  
  6241.     fp = var2fpos(&argvars[0], FALSE);
  6242.     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count)
  6243.     {
  6244.     getvcol(curwin, fp, NULL, NULL, &vcol);
  6245.     ++vcol;
  6246.     }
  6247.  
  6248.     retvar->var_val.var_number = vcol;
  6249. }
  6250.  
  6251. /*
  6252.  * "visualmode()" function
  6253.  */
  6254. /*ARGSUSED*/
  6255.     static void
  6256. f_visualmode(argvars, retvar)
  6257.     VAR        argvars;
  6258.     VAR        retvar;
  6259. {
  6260.     char_u    str[2];
  6261.  
  6262.     retvar->var_type = VAR_STRING;
  6263.     str[0] = curbuf->b_visual_mode;
  6264.     str[1] = NUL;
  6265.     retvar->var_val.var_string = vim_strsave(str);
  6266. }
  6267.  
  6268. /*
  6269.  * "winbufnr(nr)" function
  6270.  */
  6271.     static void
  6272. f_winbufnr(argvars, retvar)
  6273.     VAR        argvars;
  6274.     VAR        retvar;
  6275. {
  6276.     win_T    *wp;
  6277.  
  6278.     wp = find_win_by_nr(&argvars[0]);
  6279.     if (wp == NULL)
  6280.     retvar->var_val.var_number = -1;
  6281.     else
  6282.     retvar->var_val.var_number = wp->w_buffer->b_fnum;
  6283. }
  6284.  
  6285. /*
  6286.  * "wincol()" function
  6287.  */
  6288. /*ARGSUSED*/
  6289.     static void
  6290. f_wincol(argvars, retvar)
  6291.     VAR        argvars;
  6292.     VAR        retvar;
  6293. {
  6294.     validate_cursor();
  6295.     retvar->var_val.var_number = curwin->w_wcol + 1;
  6296. }
  6297.  
  6298. /*
  6299.  * "winheight(nr)" function
  6300.  */
  6301.     static void
  6302. f_winheight(argvars, retvar)
  6303.     VAR        argvars;
  6304.     VAR        retvar;
  6305. {
  6306.     win_T    *wp;
  6307.  
  6308.     wp = find_win_by_nr(&argvars[0]);
  6309.     if (wp == NULL)
  6310.     retvar->var_val.var_number = -1;
  6311.     else
  6312.     retvar->var_val.var_number = wp->w_height;
  6313. }
  6314.  
  6315. /*
  6316.  * "winline()" function
  6317.  */
  6318. /*ARGSUSED*/
  6319.     static void
  6320. f_winline(argvars, retvar)
  6321.     VAR        argvars;
  6322.     VAR        retvar;
  6323. {
  6324.     validate_cursor();
  6325.     retvar->var_val.var_number = curwin->w_wrow + 1;
  6326. }
  6327.  
  6328. /*
  6329.  * "winnr()" function
  6330.  */
  6331. /* ARGSUSED */
  6332.     static void
  6333. f_winnr(argvars, retvar)
  6334.     VAR        argvars;
  6335.     VAR        retvar;
  6336. {
  6337.     int        nr = 1;
  6338. #ifdef FEAT_WINDOWS
  6339.     win_T    *wp;
  6340.  
  6341.     for (wp = firstwin; wp != curwin; wp = wp->w_next)
  6342.     ++nr;
  6343. #endif
  6344.     retvar->var_val.var_number = nr;
  6345. }
  6346.  
  6347. /*
  6348.  * "winwidth(nr)" function
  6349.  */
  6350.     static void
  6351. f_winwidth(argvars, retvar)
  6352.     VAR        argvars;
  6353.     VAR        retvar;
  6354. {
  6355.     win_T    *wp;
  6356.  
  6357.     wp = find_win_by_nr(&argvars[0]);
  6358.     if (wp == NULL)
  6359.     retvar->var_val.var_number = -1;
  6360.     else
  6361. #ifdef FEAT_VERTSPLIT
  6362.     retvar->var_val.var_number = wp->w_width;
  6363. #else
  6364.     retvar->var_val.var_number = Columns;
  6365. #endif
  6366. }
  6367.  
  6368.     static win_T *
  6369. find_win_by_nr(vp)
  6370.     VAR        vp;
  6371. {
  6372. #ifdef FEAT_WINDOWS
  6373.     win_T    *wp;
  6374. #endif
  6375.     int        nr;
  6376.  
  6377.     nr = get_var_number(vp);
  6378.  
  6379. #ifdef FEAT_WINDOWS
  6380.     if (nr == 0)
  6381.     return curwin;
  6382.  
  6383.     for (wp = firstwin; wp != NULL; wp = wp->w_next)
  6384.     if (--nr <= 0)
  6385.         break;
  6386.     return wp;
  6387. #else
  6388.     if (nr == 0 || nr == 1)
  6389.     return curwin;
  6390.     return NULL;
  6391. #endif
  6392. }
  6393.  
  6394. /*
  6395.  * Translate a String variable into a position.
  6396.  */
  6397.     static pos_T *
  6398. var2fpos(varp, lnum)
  6399.     VAR        varp;
  6400.     int        lnum;        /* TRUE when $ is last line */
  6401. {
  6402.     char_u    *name;
  6403.     static pos_T    pos;
  6404.     pos_T    *pp;
  6405.  
  6406.     name = get_var_string(varp);
  6407.     if (name[0] == '.')        /* cursor */
  6408.     return &curwin->w_cursor;
  6409.     if (name[0] == '\'')    /* mark */
  6410.     {
  6411.     pp = getmark(name[1], FALSE);
  6412.     if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
  6413.         return NULL;
  6414.     return pp;
  6415.     }
  6416.     if (name[0] == '$')        /* last column or line */
  6417.     {
  6418.     if (lnum)
  6419.     {
  6420.         pos.lnum = curbuf->b_ml.ml_line_count;
  6421.         pos.col = 0;
  6422.     }
  6423.     else
  6424.     {
  6425.         pos.lnum = curwin->w_cursor.lnum;
  6426.         pos.col = (colnr_T)STRLEN(ml_get_curline());
  6427.     }
  6428.     return &pos;
  6429.     }
  6430.     return NULL;
  6431. }
  6432.  
  6433. /*
  6434.  * Get the length of an environment variable name.
  6435.  * Advance "arg" to the first character after the name.
  6436.  * Return 0 for error.
  6437.  */
  6438.     static int
  6439. get_env_len(arg)
  6440.     char_u    **arg;
  6441. {
  6442.     char_u    *p;
  6443.     int        len;
  6444.  
  6445.     for (p = *arg; vim_isIDc(*p); ++p)
  6446.     ;
  6447.     if (p == *arg)        /* no name found */
  6448.     return 0;
  6449.  
  6450.     len = (int)(p - *arg);
  6451.     *arg = p;
  6452.     return len;
  6453. }
  6454.  
  6455. /*
  6456.  * Get the length of the name of a function or internal variable.
  6457.  * "arg" is advanced to the first non-white character after the name.
  6458.  * Return 0 if something is wrong.
  6459.  */
  6460.     static int
  6461. get_id_len(arg)
  6462.     char_u    **arg;
  6463. {
  6464.     char_u    *p;
  6465.     int        len;
  6466.  
  6467.     /* Find the end of the name. */
  6468.     for (p = *arg; eval_isnamec(*p); ++p)
  6469.     ;
  6470.     if (p == *arg)        /* no name found */
  6471.     return 0;
  6472.  
  6473.     len = (int)(p - *arg);
  6474.     *arg = skipwhite(p);
  6475.  
  6476.     return len;
  6477. }
  6478.  
  6479. /*
  6480.  * Get the length of the name of a function.
  6481.  * "arg" is advanced to the first non-white character after the name.
  6482.  * Return 0 if something is wrong.
  6483.  * If the name contains 'magic' {}'s, expand them and return the
  6484.  * expanded name in an allocated string via 'alias' - caller must free.
  6485.  */
  6486.     static int
  6487. get_func_len(arg, alias)
  6488.     char_u    **arg;
  6489.     char_u    **alias;
  6490. {
  6491.     int        len;
  6492. #ifdef FEAT_MAGIC_BRACES
  6493.     char_u    *p;
  6494.     char_u    *expr_start;
  6495.     char_u    *expr_end;
  6496. #endif
  6497.  
  6498.     *alias = NULL;  /* default to no alias */
  6499.  
  6500.     if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
  6501.                           && (*arg)[2] == (int)KE_SNR)
  6502.     {
  6503.     /* hard coded <SNR>, already translated */
  6504.     *arg += 3;
  6505.     return get_id_len(arg) + 3;
  6506.     }
  6507.     len = eval_fname_script(*arg);
  6508.     if (len > 0)
  6509.     {
  6510.     /* literal "<SID>", "s:" or "<SNR>" */
  6511.     *arg += len;
  6512.     }
  6513.  
  6514. #ifdef FEAT_MAGIC_BRACES
  6515.     /*
  6516.      * Find the end of the name;
  6517.      */
  6518.     p = find_name_end(*arg, &expr_start, &expr_end);
  6519.     /* check for {} construction */
  6520.     if (expr_start != NULL)
  6521.     {
  6522.     char_u    *temp_string;
  6523.  
  6524.     /*
  6525.      * Include any <SID> etc in the expanded string:
  6526.      * Thus the -len here.
  6527.      */
  6528.     temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
  6529.     if (temp_string != NULL)
  6530.     {
  6531.         *alias = temp_string;
  6532.         *arg = skipwhite(p);
  6533.         return (int)STRLEN(temp_string);
  6534.     }
  6535.     }
  6536. #endif
  6537.  
  6538.     return get_id_len(arg) + len;
  6539. }
  6540.  
  6541.     static char_u *
  6542. find_name_end(arg, expr_start, expr_end)
  6543.     char_u    *arg;
  6544.     char_u    **expr_start;
  6545.     char_u    **expr_end;
  6546. {
  6547.     int        nesting = 0;
  6548.     char_u    *p;
  6549.  
  6550.     *expr_start = NULL;
  6551.     *expr_end = NULL;
  6552.  
  6553.     for (p = arg; (*p != NUL && (eval_isnamec(*p) || nesting != 0)); ++p)
  6554.     {
  6555. #ifdef FEAT_MAGIC_BRACES
  6556.     if (*p == '{')
  6557.     {
  6558.         nesting++;
  6559.         if (*expr_start == NULL)
  6560.         *expr_start = p;
  6561.     }
  6562.     else if (*p == '}')
  6563.     {
  6564.         nesting--;
  6565.         if (nesting == 0 && *expr_end == NULL)
  6566.         *expr_end = p;
  6567.     }
  6568. #endif
  6569.     }
  6570.  
  6571.     return p;
  6572. }
  6573.  
  6574. /*
  6575.  * Return TRUE if character "c" can be used in a variable or function name.
  6576.  */
  6577.     static int
  6578. eval_isnamec(c)
  6579.     int        c;
  6580. {
  6581.     return (ASCII_ISALPHA(c) || isdigit(c) || c == '_' || c == ':'
  6582. #ifdef FEAT_MAGIC_BRACES
  6583.         || c == '{' || c == '}'
  6584. #endif
  6585.         );
  6586. }
  6587.  
  6588. /*
  6589.  * Find a v: variable.
  6590.  * Return it's index, or -1 if not found.
  6591.  */
  6592.     static int
  6593. find_vim_var(name, len)
  6594.     char_u    *name;
  6595.     int        len;        /* length of "name" */
  6596. {
  6597.     char_u    *vname;
  6598.     int        vlen;
  6599.     int        i;
  6600.  
  6601.     /*
  6602.      * Ignore "v:" for old built-in variables, require it for new ones.
  6603.      */
  6604.     if (name[0] == 'v' && name[1] == ':')
  6605.     {
  6606.     vname = name + 2;
  6607.     vlen = len - 2;
  6608.     }
  6609.     else
  6610.     {
  6611.     vname = name;
  6612.     vlen = len;
  6613.     }
  6614.     for (i = 0; i < VV_LEN; ++i)
  6615.     if (vlen == vimvars[i].len && STRCMP(vname, vimvars[i].name) == 0
  6616.              && ((vimvars[i].flags & VV_COMPAT) || vname != name))
  6617.         return i;
  6618.     return -1;
  6619. }
  6620.  
  6621. /*
  6622.  * Set number v: variable to "val".
  6623.  */
  6624.     void
  6625. set_vim_var_nr(idx, val)
  6626.     int        idx;
  6627.     long    val;
  6628. {
  6629.     vimvars[idx].val = (char_u *)val;
  6630. }
  6631.  
  6632. /*
  6633.  * Set v:count, v:count1 and v:prevcount.
  6634.  */
  6635.     void
  6636. set_vcount(count, count1)
  6637.     long    count;
  6638.     long    count1;
  6639. {
  6640.     vimvars[VV_PREVCOUNT].val = vimvars[VV_COUNT].val;
  6641.     vimvars[VV_COUNT].val = (char_u *)count;
  6642.     vimvars[VV_COUNT1].val = (char_u *)count1;
  6643. }
  6644.  
  6645. /*
  6646.  * Set string v: variable to a copy of "val".
  6647.  */
  6648.     void
  6649. set_vim_var_string(idx, val, len)
  6650.     int        idx;
  6651.     char_u    *val;
  6652.     int        len;        /* length of "val" to use or -1 (whole string) */
  6653. {
  6654.     vim_free(vimvars[idx].val);
  6655.     if (val == NULL)
  6656.     vimvars[idx].val = NULL;
  6657.     else if (len == -1)
  6658.     vimvars[idx].val = vim_strsave(val);
  6659.     else
  6660.     vimvars[idx].val = vim_strnsave(val, len);
  6661. }
  6662.  
  6663. #if defined(FEAT_AUTOCMD) || defined(PROTO)
  6664. /*
  6665.  * Set v:cmdarg.
  6666.  * If "eap" != NULL, use "eap" to generate the value and return the old value.
  6667.  * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
  6668.  * Must always be called in pairs!
  6669.  */
  6670.     char_u *
  6671. set_cmdarg(eap, oldarg)
  6672.     exarg_T    *eap;
  6673.     char_u    *oldarg;
  6674. {
  6675.     char_u    *oldval;
  6676.     char_u    *newval;
  6677.     unsigned    len;
  6678.  
  6679.     oldval = vimvars[VV_CMDARG].val;
  6680.     if (eap != NULL)
  6681.     {
  6682.     if (eap->force_ff != 0)
  6683.         len = (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
  6684.     else
  6685.         len = 0;
  6686. # ifdef FEAT_MBYTE
  6687.     if (eap->force_enc != 0)
  6688.         len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
  6689. # endif
  6690.     newval = alloc(len + 1);
  6691.     if (newval == NULL)
  6692.         return NULL;
  6693.     if (eap->force_ff != 0)
  6694.         sprintf((char *)newval, " ++ff=%s", eap->cmd + eap->force_ff);
  6695.     else
  6696.         *newval = NUL;
  6697. # ifdef FEAT_MBYTE
  6698.     if (eap->force_enc != 0)
  6699.         sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
  6700.                            eap->cmd + eap->force_enc);
  6701. # endif
  6702.     vimvars[VV_CMDARG].val = newval;
  6703.     return oldval;
  6704.     }
  6705.  
  6706.     vim_free(oldval);
  6707.     vimvars[VV_CMDARG].val = oldarg;
  6708.     return NULL;
  6709. }
  6710. #endif
  6711.  
  6712. /*
  6713.  * Get the value of internal variable "name".
  6714.  * Return OK or FAIL.
  6715.  */
  6716.     static int
  6717. get_var_var(name, len, retvar)
  6718.     char_u    *name;
  6719.     int        len;        /* length of "name" */
  6720.     VAR        retvar;        /* NULL when only checking existence */
  6721. {
  6722.     int        ret = OK;
  6723.     int        type = VAR_UNKNOWN;
  6724.     long    number = 1;
  6725.     char_u    *string = NULL;
  6726.     VAR        v;
  6727.     int        cc;
  6728.     int        i;
  6729.  
  6730.     /* truncate the name, so that we can use strcmp() */
  6731.     cc = name[len];
  6732.     name[len] = NUL;
  6733.  
  6734.     /*
  6735.      * Check for "b:changedtick".
  6736.      */
  6737.     if (STRCMP(name, "b:changedtick") == 0)
  6738.     {
  6739.     type = VAR_NUMBER;
  6740.     number = curbuf->b_changedtick;
  6741.     }
  6742.  
  6743.     /*
  6744.      * Check for built-in v: variables.
  6745.      */
  6746.     else if ((i = find_vim_var(name, len)) >= 0)
  6747.     {
  6748.     type = vimvars[i].type;
  6749.     number = (long)vimvars[i].val;
  6750.     string = vimvars[i].val;
  6751.     }
  6752.  
  6753.     /*
  6754.      * Check for user-defined variables.
  6755.      */
  6756.     else
  6757.     {
  6758.     v = find_var(name, FALSE);
  6759.     if (v != NULL)
  6760.     {
  6761.         type = v->var_type;
  6762.         number = v->var_val.var_number;
  6763.         string = v->var_val.var_string;
  6764.     }
  6765.     }
  6766.  
  6767.     if (type == VAR_UNKNOWN)
  6768.     {
  6769.     if (retvar != NULL)
  6770.         EMSG2(_("E121: Undefined variable: %s"), name);
  6771.     ret = FAIL;
  6772.     }
  6773.     else if (retvar != NULL)
  6774.     {
  6775.     retvar->var_type = type;
  6776.     if (type == VAR_NUMBER)
  6777.         retvar->var_val.var_number = number;
  6778.     else if (type == VAR_STRING)
  6779.     {
  6780.         if (string != NULL)
  6781.         string = vim_strsave(string);
  6782.         retvar->var_val.var_string = string;
  6783.     }
  6784.     }
  6785.  
  6786.     name[len] = cc;
  6787.  
  6788.     return ret;
  6789. }
  6790.  
  6791. /*
  6792.  * Allocate memory for a variable, and make it emtpy (0 or NULL value).
  6793.  */
  6794.     static VAR
  6795. alloc_var()
  6796. {
  6797.     return (VAR)alloc_clear((unsigned)sizeof(var));
  6798. }
  6799.  
  6800. /*
  6801.  * Allocate memory for a variable, and assign a string to it.
  6802.  * The string "s" must have been allocated, it is consumed.
  6803.  * Return NULL for out of memory, the variable otherwise.
  6804.  */
  6805.     static VAR
  6806. alloc_string_var(s)
  6807.     char_u    *s;
  6808. {
  6809.     VAR        retvar;
  6810.  
  6811.     retvar = alloc_var();
  6812.     if (retvar != NULL)
  6813.     {
  6814.     retvar->var_type = VAR_STRING;
  6815.     retvar->var_val.var_string = s;
  6816.     }
  6817.     else
  6818.     vim_free(s);
  6819.     return retvar;
  6820. }
  6821.  
  6822. /*
  6823.  * Free the memory for a variable.
  6824.  */
  6825.     static void
  6826. free_var(varp)
  6827.     VAR        varp;
  6828. {
  6829.     if (varp != NULL)
  6830.     {
  6831.     if (varp->var_type == VAR_STRING)
  6832.         vim_free(varp->var_val.var_string);
  6833.     vim_free(varp->var_name);
  6834.     vim_free(varp);
  6835.     }
  6836. }
  6837.  
  6838. /*
  6839.  * Free the memory for a variable value and set the value to NULL or 0.
  6840.  */
  6841.     static void
  6842. clear_var(varp)
  6843.     VAR        varp;
  6844. {
  6845.     if (varp != NULL)
  6846.     {
  6847.     if (varp->var_type == VAR_STRING)
  6848.     {
  6849.         vim_free(varp->var_val.var_string);
  6850.         varp->var_val.var_string = NULL;
  6851.     }
  6852.     else
  6853.         varp->var_val.var_number = 0;
  6854.     }
  6855. }
  6856.  
  6857. /*
  6858.  * Get the number value of a variable.
  6859.  * If it is a String variable, use vim_str2nr().
  6860.  */
  6861.     static long
  6862. get_var_number(varp)
  6863.     VAR        varp;
  6864. {
  6865.     long    n;
  6866.  
  6867.     if (varp->var_type == VAR_NUMBER)
  6868.     return (long)(varp->var_val.var_number);
  6869.     else if (varp->var_type == VAR_UNKNOWN || varp->var_val.var_string == NULL)
  6870.     return 0L;
  6871.     else
  6872.     {
  6873.     vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL);
  6874.     return n;
  6875.     }
  6876. }
  6877.  
  6878. /*
  6879.  * Get the lnum from the first argument.  Also accepts ".", "$", etc.
  6880.  */
  6881.     static linenr_T
  6882. get_var_lnum(argvars)
  6883.     VAR        argvars;
  6884. {
  6885.     var        retvar;
  6886.     linenr_T    lnum;
  6887.  
  6888.     lnum = get_var_number(&argvars[0]);
  6889.     if (lnum == 0)  /* no valid number, try using line() */
  6890.     {
  6891.     retvar.var_type = VAR_NUMBER;
  6892.     f_line(argvars, &retvar);
  6893.     lnum = retvar.var_val.var_number;
  6894.     clear_var(&retvar);
  6895.     }
  6896.     return lnum;
  6897. }
  6898.  
  6899. /*
  6900.  * Get the string value of a variable.
  6901.  * If it is a Number variable, the number is converted into a string.
  6902.  * get_var_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
  6903.  * get_var_string_buf() uses a given buffer.
  6904.  * If the String variable has never been set, return an empty string.
  6905.  * Never returns NULL;
  6906.  */
  6907.     static char_u *
  6908. get_var_string(varp)
  6909.     VAR        varp;
  6910. {
  6911.     static char_u   mybuf[NUMBUFLEN];
  6912.  
  6913.     return get_var_string_buf(varp, mybuf);
  6914. }
  6915.  
  6916.     static char_u *
  6917. get_var_string_buf(varp, buf)
  6918.     VAR        varp;
  6919.     char_u  *buf;
  6920. {
  6921.     if (varp->var_type == VAR_NUMBER)
  6922.     {
  6923.     sprintf((char *)buf, "%ld", (long)varp->var_val.var_number);
  6924.     return buf;
  6925.     }
  6926.     else if (varp->var_val.var_string == NULL)
  6927.     return (char_u *)"";
  6928.     else
  6929.     return varp->var_val.var_string;
  6930. }
  6931.  
  6932. /*
  6933.  * Find variable "name" in the list of variables.
  6934.  * Return a pointer to it if found, NULL if not found.
  6935.  */
  6936.     static VAR
  6937. find_var(name, writing)
  6938.     char_u    *name;
  6939.     int        writing;
  6940. {
  6941.     int        i;
  6942.     char_u    *varname;
  6943.     garray_T    *gap;
  6944.  
  6945.     /* Check for function arguments "a:" */
  6946.     if (name[0] == 'a' && name[1] == ':')
  6947.     {
  6948.     if (writing)
  6949.     {
  6950.         EMSG2(_(e_readonlyvar), name);
  6951.         return NULL;
  6952.     }
  6953.     name += 2;
  6954.     if (current_funccal == NULL)
  6955.         return NULL;
  6956.     if (isdigit(*name))
  6957.     {
  6958.         i = atol((char *)name);
  6959.         if (i == 0)                    /* a:0 */
  6960.         return ¤t_funccal->a0_var;
  6961.         i += current_funccal->func->args.ga_len;
  6962.         if (i > current_funccal->argcount)        /* a:999 */
  6963.         return NULL;
  6964.         return &(current_funccal->argvars[i - 1]);    /* a:1, a:2, etc. */
  6965.     }
  6966.     if (STRCMP(name, "firstline") == 0)
  6967.         return &(current_funccal->firstline);
  6968.     if (STRCMP(name, "lastline") == 0)
  6969.         return &(current_funccal->lastline);
  6970.     for (i = 0; i < current_funccal->func->args.ga_len; ++i)
  6971.         if (STRCMP(name, ((char_u **)
  6972.                   (current_funccal->func->args.ga_data))[i]) == 0)
  6973.         return &(current_funccal->argvars[i]);    /* a:name */
  6974.     return NULL;
  6975.     }
  6976.  
  6977.     gap = find_var_ga(name, &varname);
  6978.     if (gap == NULL)
  6979.     return NULL;
  6980.     return find_var_in_ga(gap, varname);
  6981. }
  6982.  
  6983.     static VAR
  6984. find_var_in_ga(gap, varname)
  6985.     garray_T    *gap;
  6986.     char_u    *varname;
  6987. {
  6988.     int    i;
  6989.  
  6990.     for (i = gap->ga_len; --i >= 0; )
  6991.     if (VAR_GAP_ENTRY(i, gap).var_name != NULL
  6992.         && STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0)
  6993.         break;
  6994.     if (i < 0)
  6995.     return NULL;
  6996.     return &VAR_GAP_ENTRY(i, gap);
  6997. }
  6998.  
  6999. /*
  7000.  * Find the growarray and start of name without ':' for a variable name.
  7001.  */
  7002.     static garray_T *
  7003. find_var_ga(name, varname)
  7004.     char_u  *name;
  7005.     char_u  **varname;
  7006. {
  7007.     if (name[1] != ':')
  7008.     {
  7009.     *varname = name;
  7010.     if (current_funccal == NULL)
  7011.         return &variables;            /* global variable */
  7012.     return ¤t_funccal->l_vars;    /* local function variable */
  7013.     }
  7014.     *varname = name + 2;
  7015.     if (*name == 'b')                /* buffer variable */
  7016.     return &curbuf->b_vars;
  7017.     if (*name == 'w')                /* window variable */
  7018.     return &curwin->w_vars;
  7019.     if (*name == 'g')                /* global variable */
  7020.     return &variables;
  7021.     if (*name == 'l' && current_funccal != NULL)/* local function variable */
  7022.     return ¤t_funccal->l_vars;
  7023.     if (*name == 's'                /* script variable */
  7024.         && current_SID > 0 && current_SID <= ga_scripts.ga_len)
  7025.     return &SCRIPT_VARS(current_SID);
  7026.     return NULL;
  7027. }
  7028.  
  7029. /*
  7030.  * Get the string value of a global variable.
  7031.  * Returns NULL when it doesn't exit.
  7032.  */
  7033.     char_u *
  7034. get_var_value(name)
  7035.     char_u    *name;
  7036. {
  7037.     VAR        v;
  7038.  
  7039.     v = find_var(name, FALSE);
  7040.     if (v == NULL)
  7041.     return NULL;
  7042.     return get_var_string(v);
  7043. }
  7044.  
  7045. /*
  7046.  * Allocate a new growarry for a sourced script.  It will be used while
  7047.  * sourcing this script and when executing functions defined in the script.
  7048.  */
  7049.     void
  7050. new_script_vars(id)
  7051.     scid_T id;
  7052. {
  7053.     if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
  7054.     {
  7055.     while (ga_scripts.ga_len < id)
  7056.     {
  7057.         var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1));
  7058.         ++ga_scripts.ga_len;
  7059.         --ga_scripts.ga_room;
  7060.     }
  7061.     }
  7062. }
  7063.  
  7064. /*
  7065.  * Initialize internal variables for use.
  7066.  */
  7067.     void
  7068. var_init(gap)
  7069.     garray_T *gap;
  7070. {
  7071.     ga_init2(gap, (int)sizeof(var), 4);
  7072. }
  7073.  
  7074. /*
  7075.  * Clean up a list of internal variables.
  7076.  */
  7077.     void
  7078. var_clear(gap)
  7079.     garray_T *gap;
  7080. {
  7081.     int        i;
  7082.  
  7083.     for (i = gap->ga_len; --i >= 0; )
  7084.     var_free_one(&VAR_GAP_ENTRY(i, gap));
  7085.     ga_clear(gap);
  7086. }
  7087.  
  7088.     static void
  7089. var_free_one(v)
  7090.     VAR        v;
  7091. {
  7092.     vim_free(v->var_name);
  7093.     v->var_name = NULL;
  7094.     if (v->var_type == VAR_STRING)
  7095.     vim_free(v->var_val.var_string);
  7096.     v->var_val.var_string = NULL;
  7097. }
  7098.  
  7099. /*
  7100.  * List the value of one internal variable.
  7101.  */
  7102.     static void
  7103. list_one_var(v, prefix)
  7104.     VAR        v;
  7105.     char_u    *prefix;
  7106. {
  7107.     list_one_var_a(prefix, v->var_name, v->var_type, get_var_string(v));
  7108. }
  7109.  
  7110. /*
  7111.  * List the value of one "v:" variable.
  7112.  */
  7113.     static void
  7114. list_vim_var(i)
  7115.     int        i;    /* index in vimvars[] */
  7116. {
  7117.     char_u    *p;
  7118.     char_u    numbuf[NUMBUFLEN];
  7119.  
  7120.     if (vimvars[i].type == VAR_NUMBER)
  7121.     {
  7122.     p = numbuf;
  7123.     sprintf((char *)p, "%ld", (long)vimvars[i].val);
  7124.     }
  7125.     else if (vimvars[i].val == NULL)
  7126.     p = (char_u *)"";
  7127.     else
  7128.     p = vimvars[i].val;
  7129.     list_one_var_a((char_u *)"v:", (char_u *)vimvars[i].name,
  7130.                               vimvars[i].type, p);
  7131. }
  7132.  
  7133.     static void
  7134. list_one_var_a(prefix, name, type, string)
  7135.     char_u    *prefix;
  7136.     char_u    *name;
  7137.     int        type;
  7138.     char_u    *string;
  7139. {
  7140.     msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
  7141.     if (name != NULL)    /* "a:" vars don't have a name stored */
  7142.     msg_puts(name);
  7143.     msg_putchar(' ');
  7144.     msg_advance(22);
  7145.     if (type == VAR_NUMBER)
  7146.     msg_putchar('#');
  7147.     else
  7148.     msg_putchar(' ');
  7149.     msg_outtrans(string);
  7150. }
  7151.  
  7152. /*
  7153.  * Set variable "name" to value in "varp".
  7154.  * If the variable already exists, the value is updated.
  7155.  * Otherwise the variable is created.
  7156.  */
  7157.     static void
  7158. set_var(name, varp)
  7159.     char_u    *name;
  7160.     VAR        varp;
  7161. {
  7162.     int        i;
  7163.     VAR        v;
  7164.     char_u    *varname;
  7165.     garray_T    *gap;
  7166.  
  7167.     /*
  7168.      * Handle setting internal v: variables.
  7169.      */
  7170.     i = find_vim_var(name, (int)STRLEN(name));
  7171.     if (i >= 0)
  7172.     {
  7173.     if (vimvars[i].flags & VV_RO)
  7174.         EMSG2(_(e_readonlyvar), name);
  7175.     else
  7176.     {
  7177.         if (vimvars[i].type == VAR_STRING)
  7178.         {
  7179.         vim_free(vimvars[i].val);
  7180.         vimvars[i].val = vim_strsave(get_var_string(varp));
  7181.         }
  7182.         else
  7183.         vimvars[i].val = (char_u *)(long)varp->var_val.var_number;
  7184.     }
  7185.     return;
  7186.     }
  7187.  
  7188.     v = find_var(name, TRUE);
  7189.     if (v != NULL)        /* existing variable, only need to free string */
  7190.     {
  7191.     if (v->var_type == VAR_STRING)
  7192.         vim_free(v->var_val.var_string);
  7193.     }
  7194.     else            /* add a new variable */
  7195.     {
  7196.     gap = find_var_ga(name, &varname);
  7197.     if (gap == NULL)    /* illegal name */
  7198.         return;
  7199.  
  7200.     /* Try to use an empty entry */
  7201.     for (i = gap->ga_len; --i >= 0; )
  7202.         if (VAR_GAP_ENTRY(i, gap).var_name == NULL)
  7203.         break;
  7204.     if (i < 0)        /* need to allocate more room */
  7205.     {
  7206.         if (ga_grow(gap, 1) == FAIL)
  7207.         return;
  7208.         i = gap->ga_len;
  7209.     }
  7210.     v = &VAR_GAP_ENTRY(i, gap);
  7211.     if ((v->var_name = vim_strsave(varname)) == NULL)
  7212.         return;
  7213.     if (i == gap->ga_len)
  7214.     {
  7215.         ++gap->ga_len;
  7216.         --gap->ga_room;
  7217.     }
  7218.     }
  7219.     copy_var(varp, v);
  7220. }
  7221.  
  7222.     static void
  7223. copy_var(from, to)
  7224.     VAR    from;
  7225.     VAR    to;
  7226. {
  7227.     to->var_type = from->var_type;
  7228.     if (from->var_type == VAR_STRING)
  7229.     to->var_val.var_string = vim_strsave(get_var_string(from));
  7230.     else
  7231.     to->var_val.var_number = from->var_val.var_number;
  7232. }
  7233.  
  7234. /*
  7235.  * ":echo expr1 ..."    print each argument separated with a space, add a
  7236.  *            newline at the end.
  7237.  * ":echon expr1 ..."    print each argument plain.
  7238.  */
  7239.     void
  7240. ex_echo(eap)
  7241.     exarg_T    *eap;
  7242. {
  7243.     char_u    *arg = eap->arg;
  7244.     var        retvar;
  7245.     char_u    *p;
  7246.     int        needclr = TRUE;
  7247.     int        atstart = TRUE;
  7248.  
  7249.     if (eap->skip)
  7250.     ++emsg_skip;
  7251.     else if (eap->cmdidx == CMD_echo)
  7252.     msg_start();
  7253.     while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
  7254.     {
  7255.     p = arg;
  7256.     if (eval1(&arg, &retvar, !eap->skip) == FAIL)
  7257.     {
  7258.         EMSG2(_(e_invexpr2), p);
  7259.         break;
  7260.     }
  7261.     if (!eap->skip)
  7262.     {
  7263.         if (atstart)
  7264.         atstart = FALSE;
  7265.         else if (eap->cmdidx == CMD_echo)
  7266.         msg_puts_attr((char_u *)" ", echo_attr);
  7267.         for (p = get_var_string(&retvar); *p != NUL && !got_int; ++p)
  7268.         if (*p == '\n' || *p == '\r' || *p == TAB)
  7269.         {
  7270.             if (*p != TAB && needclr)
  7271.             {
  7272.             /* remove any text still there from the command */
  7273.             msg_clr_eos();
  7274.             needclr = FALSE;
  7275.             }
  7276.             msg_putchar_attr(*p, echo_attr);
  7277.         }
  7278.         else
  7279.         {
  7280. #ifdef FEAT_MBYTE
  7281.             if (has_mbyte)
  7282.             {
  7283.             int i = (*mb_ptr2len_check)(p);
  7284.  
  7285.             (void)msg_outtrans_len_attr(p, i, echo_attr);
  7286.             p += i - 1;
  7287.             }
  7288.             else
  7289. #endif
  7290.             (void)msg_outtrans_len_attr(p, 1, echo_attr);
  7291.         }
  7292.     }
  7293.     clear_var(&retvar);
  7294.     arg = skipwhite(arg);
  7295.     }
  7296.     eap->nextcmd = check_nextcmd(arg);
  7297.  
  7298.     if (eap->skip)
  7299.     --emsg_skip;
  7300.     else
  7301.     {
  7302.     /* remove text that may still be there from the command */
  7303.     if (needclr)
  7304.         msg_clr_eos();
  7305.     if (eap->cmdidx == CMD_echo)
  7306.         msg_end();
  7307.     }
  7308. }
  7309.  
  7310. /*
  7311.  * ":echohl {name}".
  7312.  */
  7313.     void
  7314. ex_echohl(eap)
  7315.     exarg_T    *eap;
  7316. {
  7317.     int        id;
  7318.  
  7319.     id = syn_name2id(eap->arg);
  7320.     if (id == 0)
  7321.     echo_attr = 0;
  7322.     else
  7323.     echo_attr = syn_id2attr(id);
  7324. }
  7325.  
  7326. /*
  7327.  * ":execute expr1 ..."    execute the result of an expression.
  7328.  * ":echomsg expr1 ..."    Print a message
  7329.  * ":echoerr expr1 ..."    Print an error
  7330.  * Each gets spaces around each argument and a newline at the end for
  7331.  * echo commands
  7332.  */
  7333.     void
  7334. ex_execute(eap)
  7335.     exarg_T    *eap;
  7336. {
  7337.     char_u    *arg = eap->arg;
  7338.     var        retvar;
  7339.     int        ret = OK;
  7340.     char_u    *p;
  7341.     garray_T    ga;
  7342.     int        len;
  7343.     int        save_did_emsg;
  7344.  
  7345.     ga_init2(&ga, 1, 80);
  7346.  
  7347.     if (eap->skip)
  7348.     ++emsg_skip;
  7349.     while (*arg != NUL && *arg != '|' && *arg != '\n')
  7350.     {
  7351.     p = arg;
  7352.     if (eval1(&arg, &retvar, !eap->skip) == FAIL)
  7353.     {
  7354.         EMSG2(_(e_invexpr2), p);
  7355.         ret = FAIL;
  7356.         break;
  7357.     }
  7358.  
  7359.     if (!eap->skip)
  7360.     {
  7361.         p = get_var_string(&retvar);
  7362.         len = (int)STRLEN(p);
  7363.         if (ga_grow(&ga, len + 2) == FAIL)
  7364.         {
  7365.         clear_var(&retvar);
  7366.         ret = FAIL;
  7367.         break;
  7368.         }
  7369.         if (ga.ga_len)
  7370.         {
  7371.         ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
  7372.         --ga.ga_room;
  7373.         }
  7374.         STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
  7375.         ga.ga_room -= len;
  7376.         ga.ga_len += len;
  7377.     }
  7378.  
  7379.     clear_var(&retvar);
  7380.     arg = skipwhite(arg);
  7381.     }
  7382.  
  7383.     if (ret != FAIL && ga.ga_data != NULL)
  7384.     {
  7385.     if (eap->cmdidx == CMD_echomsg)
  7386.         MSG((char_u *)ga.ga_data);
  7387.     else if (eap->cmdidx == CMD_echoerr)
  7388.     {
  7389.         /* We don't want to abort following commands, restore did_emsg. */
  7390.         save_did_emsg = did_emsg;
  7391.         EMSG((char_u *)ga.ga_data);
  7392.         did_emsg = save_did_emsg;
  7393.     }
  7394.     else if (eap->cmdidx == CMD_execute)
  7395.         do_cmdline((char_u *)ga.ga_data,
  7396.                eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
  7397.     }
  7398.  
  7399.     ga_clear(&ga);
  7400.  
  7401.     if (eap->skip)
  7402.     --emsg_skip;
  7403.  
  7404.     eap->nextcmd = check_nextcmd(arg);
  7405. }
  7406.  
  7407. /*
  7408.  * Skip over the name of an option: "&option", "&g:option" or "&l:option".
  7409.  * "arg" points to the "&" when called, to "option" when returning.
  7410.  * Returns NULL when no option name found.  Otherwise pointer to the char
  7411.  * after the option name.
  7412.  */
  7413.     static char_u *
  7414. find_option_end(arg, opt_flags)
  7415.     char_u    **arg;
  7416.     int        *opt_flags;
  7417. {
  7418.     char_u    *p = *arg;
  7419.  
  7420.     ++p;
  7421.     if (*p == 'g' && p[1] == ':')
  7422.     {
  7423.     *opt_flags = OPT_GLOBAL;
  7424.     p += 2;
  7425.     }
  7426.     else if (*p == 'l' && p[1] == ':')
  7427.     {
  7428.     *opt_flags = OPT_LOCAL;
  7429.     p += 2;
  7430.     }
  7431.     else
  7432.     *opt_flags = 0;
  7433.  
  7434.     if (!ASCII_ISALPHA(*p))
  7435.     return NULL;
  7436.     *arg = p;
  7437.  
  7438.     if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
  7439.     p += 4;        /* termcap option */
  7440.     else
  7441.     while (ASCII_ISALPHA(*p))
  7442.         ++p;
  7443.     return p;
  7444. }
  7445.  
  7446. /*
  7447.  * ":function"
  7448.  */
  7449.     void
  7450. ex_function(eap)
  7451.     exarg_T    *eap;
  7452. {
  7453.     char_u    *theline;
  7454.     int        j;
  7455.     int        c;
  7456.     char_u    *name = NULL;
  7457.     char_u    *p;
  7458.     char_u    *arg;
  7459.     garray_T    newargs;
  7460.     garray_T    newlines;
  7461.     int        varargs = FALSE;
  7462.     int        mustend = FALSE;
  7463.     int        flags = 0;
  7464.     ufunc_T    *fp;
  7465.     int        indent;
  7466.     int        nesting;
  7467.     int        in_append = FALSE;
  7468.     static char_u e_funcexts[] = N_("E122: Function %s already exists, use ! to replace");
  7469.  
  7470.     /*
  7471.      * ":function" without argument: list functions.
  7472.      */
  7473.     if (*eap->arg == NUL)
  7474.     {
  7475.     if (!eap->skip)
  7476.         for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next)
  7477.         list_func_head(fp);
  7478.     return;
  7479.     }
  7480.  
  7481.     p = eap->arg;
  7482.     name = trans_function_name(&p);
  7483.     if (name == NULL && !eap->skip)
  7484.     return;
  7485.  
  7486.     /*
  7487.      * ":function func" with only function name: list function.
  7488.      */
  7489.     if (vim_strchr(eap->arg, '(') == NULL)
  7490.     {
  7491.     if (!eap->skip)
  7492.     {
  7493.         fp = find_func(name);
  7494.         if (fp != NULL)
  7495.         {
  7496.         list_func_head(fp);
  7497.         for (j = 0; j < fp->lines.ga_len; ++j)
  7498.         {
  7499.             msg_putchar('\n');
  7500.             msg_outnum((long)(j + 1));
  7501.             do
  7502.             {
  7503.             msg_putchar(' ');
  7504.             } while (msg_col < 3);
  7505.             msg_prt_line(FUNCLINE(fp, j));
  7506.         }
  7507.         MSG("   endfunction");
  7508.         }
  7509.         else
  7510.         EMSG2(_("E123: Undefined function: %s"), eap->arg);
  7511.     }
  7512.     goto erret_name;
  7513.     }
  7514.  
  7515.     /*
  7516.      * ":function name(arg1, arg2)" Define function.
  7517.      */
  7518.     p = skipwhite(p);
  7519.     if (*p != '(')
  7520.     {
  7521.     if (!eap->skip)
  7522.     {
  7523.         EMSG2(_("E124: Missing '(': %s"), eap->arg);
  7524.         goto erret_name;
  7525.     }
  7526.     /* attempt to continue by skipping some text */
  7527.     if (vim_strchr(p, '(') != NULL)
  7528.         p = vim_strchr(p, '(');
  7529.     }
  7530.     p = skipwhite(p + 1);
  7531.  
  7532.     ga_init2(&newargs, (int)sizeof(char_u *), 3);
  7533.     ga_init2(&newlines, (int)sizeof(char_u *), 3);
  7534.  
  7535.     /*
  7536.      * Isolate the arguments: "arg1, arg2, ...)"
  7537.      */
  7538.     while (*p != ')')
  7539.     {
  7540.     if (p[0] == '.' && p[1] == '.' && p[2] == '.')
  7541.     {
  7542.         varargs = TRUE;
  7543.         p += 3;
  7544.         mustend = TRUE;
  7545.     }
  7546.     else
  7547.     {
  7548.         arg = p;
  7549.         while (ASCII_ISALPHA(*p) || isdigit(*p) || *p == '_')
  7550.         ++p;
  7551.         if (arg == p || isdigit(*arg))
  7552.         {
  7553.         if (eap->skip)
  7554.             break;
  7555.         EMSG2(_("E125: Illegal argument: %s"), arg);
  7556.         goto erret;
  7557.         }
  7558.         if (ga_grow(&newargs, 1) == FAIL)
  7559.         goto erret;
  7560.         c = *p;
  7561.         *p = NUL;
  7562.         arg = vim_strsave(arg);
  7563.         if (arg == NULL)
  7564.         goto erret;
  7565.         ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
  7566.         *p = c;
  7567.         newargs.ga_len++;
  7568.         newargs.ga_room--;
  7569.         if (*p == ',')
  7570.         ++p;
  7571.         else
  7572.         mustend = TRUE;
  7573.     }
  7574.     p = skipwhite(p);
  7575.     if (mustend && *p != ')')
  7576.     {
  7577.         if (eap->skip)
  7578.         break;
  7579.         EMSG2(_(e_invarg2), eap->arg);
  7580.         goto erret;
  7581.     }
  7582.     }
  7583.     ++p;    /* skip the ')' */
  7584.  
  7585.     /* find extra arguments "range" and "abort" */
  7586.     for (;;)
  7587.     {
  7588.     p = skipwhite(p);
  7589.     if (STRNCMP(p, "range", 5) == 0)
  7590.     {
  7591.         flags |= FC_RANGE;
  7592.         p += 5;
  7593.     }
  7594.     else if (STRNCMP(p, "abort", 5) == 0)
  7595.     {
  7596.         flags |= FC_ABORT;
  7597.         p += 5;
  7598.     }
  7599.     else
  7600.         break;
  7601.     }
  7602.  
  7603.     if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip)
  7604.     {
  7605.     EMSG(_(e_trailing));
  7606.     goto erret;
  7607.     }
  7608.  
  7609.     /*
  7610.      * Read the body of the function, until ":endfunction" is found.
  7611.      */
  7612.     if (KeyTyped)
  7613.     {
  7614.     /* Check if the function already exists, don't let the user type the
  7615.      * whole function before telling him it doesn't work!  For a script we
  7616.      * need to skip the body to be able to find what follows. */
  7617.     if (find_func(name) != NULL && !eap->forceit)
  7618.     {
  7619.         EMSG2(_(e_funcexts), name);
  7620.         goto erret;
  7621.     }
  7622.  
  7623.     msg_putchar('\n');        /* don't overwrite the function name */
  7624.     cmdline_row = msg_row;
  7625.     }
  7626.  
  7627.     indent = 2;
  7628.     nesting = 0;
  7629.     for (;;)
  7630.     {
  7631.     msg_scroll = TRUE;
  7632.     need_wait_return = FALSE;
  7633.     if (eap->getline == NULL)
  7634.         theline = getcmdline(':', 0L, indent);
  7635.     else
  7636.         theline = eap->getline(':', eap->cookie, indent);
  7637.     if (KeyTyped)
  7638.         lines_left = Rows - 1;
  7639.     if (theline == NULL)
  7640.     {
  7641.         EMSG(_("E126: Missing :endfunction"));
  7642.         goto erret;
  7643.     }
  7644.  
  7645.     if (in_append)
  7646.     {
  7647.         /* between ":append" and "." there is no check for ":endfunc". */
  7648.         if (theline[0] == '.' && theline[1] == NUL)
  7649.         in_append = FALSE;
  7650.     }
  7651.     else
  7652.     {
  7653.         /* skip ':' and blanks*/
  7654.         for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
  7655.         ;
  7656.  
  7657.         /* Check for "endfunction" (should be more strict...). */
  7658.         if (STRNCMP(p, "endf", 4) == 0 && nesting-- == 0)
  7659.         {
  7660.         vim_free(theline);
  7661.         break;
  7662.         }
  7663.  
  7664.         /* Increase indent inside "if" and "while", decrease at "end" */
  7665.         if (indent > 2 && STRNCMP(p, "end", 3) == 0)
  7666.         indent -= 2;
  7667.         else if (STRNCMP(p, "if", 2) == 0 || STRNCMP(p, "wh", 2) == 0)
  7668.         indent += 2;
  7669.  
  7670.         /* Check for defining a function inside this function. */
  7671.         if (STRNCMP(p, "fu", 2) == 0)
  7672.         {
  7673.         p = skipwhite(skiptowhite(p));
  7674.         p += eval_fname_script(p);
  7675.         if (ASCII_ISALPHA(*p))
  7676.         {
  7677.             while (ASCII_ISALPHA(*p) || isdigit(*p) || *p == '_')
  7678.             ++p;
  7679.             if (*skipwhite(p) == '(')
  7680.             {
  7681.             ++nesting;
  7682.             indent += 2;
  7683.             }
  7684.         }
  7685.         }
  7686.  
  7687.         /* Check for ":append" or ":insert". */
  7688.         p = skip_range(p, NULL);
  7689.         if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
  7690.             || (p[0] == 'i'
  7691.             && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
  7692.                 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
  7693.         in_append = TRUE;
  7694.     }
  7695.  
  7696.     /* Add the line to the function. */
  7697.     if (ga_grow(&newlines, 1) == FAIL)
  7698.         goto erret;
  7699.     ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline;
  7700.     newlines.ga_len++;
  7701.     newlines.ga_room--;
  7702.     }
  7703.  
  7704.     if (eap->skip)
  7705.     goto erret;
  7706.  
  7707.     /*
  7708.      * If there are no errors, add the function
  7709.      */
  7710.     fp = find_func(name);
  7711.     if (fp != NULL)
  7712.     {
  7713.     if (!eap->forceit)
  7714.     {
  7715.         EMSG2(_(e_funcexts), name);
  7716.         goto erret;
  7717.     }
  7718.     if (fp->calls)
  7719.     {
  7720.         EMSG2(_("E127: Cannot redefine function %s: It is in use"), name);
  7721.         goto erret;
  7722.     }
  7723.     /* redefine existing function */
  7724.     ga_clear_strings(&(fp->args));
  7725.     ga_clear_strings(&(fp->lines));
  7726.     }
  7727.     else
  7728.     {
  7729.     fp = (ufunc_T *)alloc((unsigned)sizeof(ufunc_T));
  7730.     if (fp == NULL)
  7731.         goto erret;
  7732.     /* insert the new function in the function list */
  7733.     fp->next = firstfunc;
  7734.     firstfunc = fp;
  7735.     fp->name = name;
  7736.     }
  7737.     fp->args = newargs;
  7738.     fp->lines = newlines;
  7739.     fp->varargs = varargs;
  7740.     fp->flags = flags;
  7741.     fp->calls = 0;
  7742.     fp->script_ID = current_SID;
  7743.     return;
  7744.  
  7745. erret:
  7746.     ga_clear_strings(&newargs);
  7747.     ga_clear_strings(&newlines);
  7748. erret_name:
  7749.     vim_free(name);
  7750. }
  7751.  
  7752. /*
  7753.  * Get a function name, translating "<SID>" and "<SNR>".
  7754.  * Returns the function name in allocated memory, or NULL for failure.
  7755.  * Advances "pp" to just after the function name (if no error).
  7756.  */
  7757.     static char_u *
  7758. trans_function_name(pp)
  7759.     char_u    **pp;
  7760. {
  7761.     char_u    *name;
  7762.     char_u    *start;
  7763.     char_u    *end;
  7764.     int        lead;
  7765.     char_u    sid_buf[20];
  7766.     char_u    *temp_string = NULL;
  7767.     char_u    *expr_start, *expr_end;
  7768.     int        len;
  7769.  
  7770.     /* A name starting with "<SID>" or "<SNR>" is local to a script. */
  7771.     start = *pp;
  7772.     lead = eval_fname_script(start);
  7773.     if (lead > 0)
  7774.     start += lead;
  7775.     else if (!ASCII_ISUPPER(*start))
  7776.     {
  7777.     EMSG2(_("E128: Function name must start with a capital: %s"), start);
  7778.     return NULL;
  7779.     }
  7780.     end = find_name_end(start, &expr_start, &expr_end);
  7781.     if (end == start)
  7782.     {
  7783.     EMSG(_("E129: Function name required"));
  7784.     return NULL;
  7785.     }
  7786.     if (expr_start != NULL)
  7787.     {
  7788.     /* expand magic curlies */
  7789.     temp_string = make_expanded_name(start, expr_start, expr_end, end);
  7790.     if (temp_string == NULL)
  7791.         return NULL;
  7792.     start = temp_string;
  7793.     len = (int)STRLEN(temp_string);
  7794.     }
  7795.     else
  7796.     len = (int)(end - start);
  7797.  
  7798.     /*
  7799.      * Copy the function name to allocated memory.
  7800.      * Accept <SID>name() inside a script, translate into <SNR>123_name().
  7801.      * Accept <SNR>123_name() outside a script.
  7802.      */
  7803.     if (lead > 0)
  7804.     {
  7805.     lead = 3;
  7806.     if (eval_fname_sid(*pp))    /* If it's "<SID>" */
  7807.     {
  7808.         if (current_SID <= 0)
  7809.         {
  7810.         EMSG(_(e_usingsid));
  7811.         return NULL;
  7812.         }
  7813.         sprintf((char *)sid_buf, "%ld_", (long)current_SID);
  7814.         lead += (int)STRLEN(sid_buf);
  7815.     }
  7816.     }
  7817.     else
  7818.     lead = 0;
  7819.     name = alloc((unsigned)(len + lead + 1));
  7820.     if (name != NULL)
  7821.     {
  7822.     if (lead > 0)
  7823.     {
  7824.         name[0] = K_SPECIAL;
  7825.         name[1] = KS_EXTRA;
  7826.         name[2] = (int)KE_SNR;
  7827.         if (eval_fname_sid(*pp))    /* If it's "<SID>" */
  7828.         STRCPY(name + 3, sid_buf);
  7829.     }
  7830.     mch_memmove(name + lead, start, (size_t)len);
  7831.     name[len + lead] = NUL;
  7832.     }
  7833.     *pp = end;
  7834.  
  7835.     vim_free(temp_string);
  7836.     return name;
  7837. }
  7838.  
  7839. /*
  7840.  * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
  7841.  * Return 2 if "p" starts with "s:".
  7842.  * Return 0 otherwise.
  7843.  */
  7844.     static int
  7845. eval_fname_script(p)
  7846.     char_u    *p;
  7847. {
  7848.     if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
  7849.                       || STRNICMP(p + 1, "SNR>", 4) == 0))
  7850.     return 5;
  7851.     if (p[0] == 's' && p[1] == ':')
  7852.     return 2;
  7853.     return 0;
  7854. }
  7855.  
  7856. /*
  7857.  * Return TRUE if "p" starts with "<SID>" or "s:".
  7858.  * Only works if eval_fname_script() returned non-zero for "p"!
  7859.  */
  7860.     static int
  7861. eval_fname_sid(p)
  7862.     char_u    *p;
  7863. {
  7864.     return (*p == 's' || TO_UPPER(p[2]) == 'I');
  7865. }
  7866.  
  7867. /*
  7868.  * List the head of the function: "name(arg1, arg2)".
  7869.  */
  7870.     static void
  7871. list_func_head(fp)
  7872.     ufunc_T    *fp;
  7873. {
  7874.     int        j;
  7875.  
  7876.     MSG(_("function "));
  7877.     if (fp->name[0] == K_SPECIAL)
  7878.     {
  7879.     MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
  7880.     msg_puts(fp->name + 3);
  7881.     }
  7882.     else
  7883.     msg_puts(fp->name);
  7884.     msg_putchar('(');
  7885.     for (j = 0; j < fp->args.ga_len; ++j)
  7886.     {
  7887.     if (j)
  7888.         MSG_PUTS(", ");
  7889.     msg_puts(FUNCARG(fp, j));
  7890.     }
  7891.     if (fp->varargs)
  7892.     {
  7893.     if (j)
  7894.         MSG_PUTS(", ");
  7895.     MSG_PUTS("...");
  7896.     }
  7897.     msg_putchar(')');
  7898. }
  7899.  
  7900. /*
  7901.  * Find a function by name, return pointer to it in ufuncs.
  7902.  * Return NULL for unknown function.
  7903.  */
  7904.     static ufunc_T *
  7905. find_func(name)
  7906.     char_u    *name;
  7907. {
  7908.     ufunc_T    *fp;
  7909.  
  7910.     for (fp = firstfunc; fp != NULL; fp = fp->next)
  7911.     if (STRCMP(name, fp->name) == 0)
  7912.         break;
  7913.     return fp;
  7914. }
  7915.  
  7916. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  7917.  
  7918. /*
  7919.  * Function given to ExpandGeneric() to obtain the list of user defined
  7920.  * function names.
  7921.  */
  7922.     char_u *
  7923. get_user_func_name(xp, idx)
  7924.     expand_T    *xp;
  7925.     int        idx;
  7926. {
  7927.     static ufunc_T *fp = NULL;
  7928.  
  7929.     if (idx == 0)
  7930.     fp = firstfunc;
  7931.     if (fp != NULL)
  7932.     {
  7933.     if (STRLEN(fp->name) + 4 >= IOSIZE)
  7934.         return fp->name;    /* prevents overflow */
  7935.  
  7936.     cat_func_name(IObuff, fp);
  7937.     if (xp->xp_context != EXPAND_USER_FUNC)
  7938.     {
  7939.         STRCAT(IObuff, "(");
  7940.         if (!fp->varargs && fp->args.ga_len == 0)
  7941.         STRCAT(IObuff, ")");
  7942.     }
  7943.  
  7944.     fp = fp->next;
  7945.     return IObuff;
  7946.     }
  7947.     return NULL;
  7948. }
  7949.  
  7950. #endif /* FEAT_CMDL_COMPL */
  7951.  
  7952. /*
  7953.  * Copy the function name of "fp" to buffer "buf".
  7954.  * "buf" must be able to hold the function name plus three bytes.
  7955.  * Takes care of script-local function names.
  7956.  */
  7957.     static void
  7958. cat_func_name(buf, fp)
  7959.     char_u    *buf;
  7960.     ufunc_T    *fp;
  7961. {
  7962.     if (fp->name[0] == K_SPECIAL)
  7963.     {
  7964.     STRCPY(buf, "<SNR>");
  7965.     STRCAT(buf, fp->name + 3);
  7966.     }
  7967.     else
  7968.     STRCPY(buf, fp->name);
  7969. }
  7970.  
  7971. /*
  7972.  * ":delfunction {name}"
  7973.  */
  7974.     void
  7975. ex_delfunction(eap)
  7976.     exarg_T    *eap;
  7977. {
  7978.     ufunc_T    *fp, *pfp;
  7979.     char_u    *p;
  7980.     char_u    *name;
  7981.  
  7982.     p = eap->arg;
  7983.     name = trans_function_name(&p);
  7984.     if (name == NULL)
  7985.     return;
  7986.     fp = find_func(name);
  7987.     vim_free(name);
  7988.  
  7989.     if (fp == NULL)
  7990.     {
  7991.     EMSG2(_("E130: Undefined function: %s"), eap->arg);
  7992.     return;
  7993.     }
  7994.     if (fp->calls)
  7995.     {
  7996.     EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
  7997.     return;
  7998.     }
  7999.  
  8000.     /* clear this function */
  8001.     vim_free(fp->name);
  8002.     ga_clear_strings(&(fp->args));
  8003.     ga_clear_strings(&(fp->lines));
  8004.  
  8005.     /* remove the function from the function list */
  8006.     if (firstfunc == fp)
  8007.     firstfunc = fp->next;
  8008.     else
  8009.     {
  8010.     for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
  8011.         if (pfp->next == fp)
  8012.         {
  8013.         pfp->next = fp->next;
  8014.         break;
  8015.         }
  8016.     }
  8017.     vim_free(fp);
  8018. }
  8019.  
  8020. /*
  8021.  * Call a user function.
  8022.  */
  8023.     static void
  8024. call_func(fp, argcount, argvars, retvar, firstline, lastline)
  8025.     ufunc_T    *fp;        /* pointer to function */
  8026.     int        argcount;    /* nr of args */
  8027.     VAR        argvars;    /* arguments */
  8028.     VAR        retvar;        /* return value */
  8029.     linenr_T    firstline;    /* first line of range */
  8030.     linenr_T    lastline;    /* last line of range */
  8031. {
  8032.     char_u        *save_sourcing_name;
  8033.     linenr_T        save_sourcing_lnum;
  8034.     scid_T        save_current_SID;
  8035.     struct funccall    fc;
  8036.     struct funccall    *save_fcp = current_funccal;
  8037.     int            save_did_emsg;
  8038.     static int        depth = 0;
  8039.  
  8040.     /* If depth of calling is getting too high, don't execute the function */
  8041.     if (depth >= p_mfd)
  8042.     {
  8043.     EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
  8044.     retvar->var_type = VAR_NUMBER;
  8045.     retvar->var_val.var_number = -1;
  8046.     return;
  8047.     }
  8048.     ++depth;
  8049.  
  8050.     line_breakcheck();        /* check for CTRL-C hit */
  8051.  
  8052.     /* set local variables */
  8053.     var_init(&fc.l_vars);
  8054.     fc.func = fp;
  8055.     fc.argcount = argcount;
  8056.     fc.argvars = argvars;
  8057.     fc.retvar = retvar;
  8058.     retvar->var_val.var_number = 0;
  8059.     fc.linenr = 0;
  8060.     fc.a0_var.var_type = VAR_NUMBER;
  8061.     fc.a0_var.var_val.var_number = argcount - fp->args.ga_len;
  8062.     fc.a0_var.var_name = NULL;
  8063.     current_funccal = &fc;
  8064.     fc.firstline.var_type = VAR_NUMBER;
  8065.     fc.firstline.var_val.var_number = firstline;
  8066.     fc.firstline.var_name = NULL;
  8067.     fc.lastline.var_type = VAR_NUMBER;
  8068.     fc.lastline.var_val.var_number = lastline;
  8069.     fc.lastline.var_name = NULL;
  8070.     /* Check if this function has a breakpoint. */
  8071.     fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0);
  8072.     fc.dbg_tick = debug_tick;
  8073.  
  8074.     /* Don't redraw while executing the function. */
  8075.     ++RedrawingDisabled;
  8076.     save_sourcing_name = sourcing_name;
  8077.     save_sourcing_lnum = sourcing_lnum;
  8078.     sourcing_lnum = 1;
  8079.     sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
  8080.         : STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 13));
  8081.     if (sourcing_name != NULL)
  8082.     {
  8083.     if (save_sourcing_name != NULL
  8084.               && STRNCMP(save_sourcing_name, "function ", 9) == 0)
  8085.         sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
  8086.     else
  8087.         STRCPY(sourcing_name, "function ");
  8088.     cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
  8089.  
  8090.     if (p_verbose >= 12)
  8091.     {
  8092.         ++no_wait_return;
  8093.         msg_scroll = TRUE;        /* always scroll up, don't overwrite */
  8094.         smsg((char_u *)_("calling %s"), sourcing_name);
  8095.         msg_puts((char_u *)"\n");   /* don't overwrite this either */
  8096.         cmdline_row = msg_row;
  8097.         --no_wait_return;
  8098.     }
  8099.     }
  8100.     save_current_SID = current_SID;
  8101.     current_SID = fp->script_ID;
  8102.     save_did_emsg = did_emsg;
  8103.     did_emsg = FALSE;
  8104.  
  8105.     /* call do_cmdline() to execute the lines */
  8106.     do_cmdline(NULL, get_func_line, (void *)&fc,
  8107.                      DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
  8108.  
  8109.     --RedrawingDisabled;
  8110.     vim_free(sourcing_name);
  8111.     sourcing_name = save_sourcing_name;
  8112.     sourcing_lnum = save_sourcing_lnum;
  8113.     current_SID = save_current_SID;
  8114.  
  8115.     if (p_verbose >= 12 && sourcing_name != NULL)
  8116.     {
  8117.     ++no_wait_return;
  8118.     msg_scroll = TRUE;        /* always scroll up, don't overwrite */
  8119.     smsg((char_u *)_("continuing in %s"), sourcing_name);
  8120.     msg_puts((char_u *)"\n");   /* don't overwrite this either */
  8121.     cmdline_row = msg_row;
  8122.     --no_wait_return;
  8123.     }
  8124.  
  8125.     /* when the function was aborted because of an error, return -1 */
  8126.     if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->var_type == VAR_UNKNOWN)
  8127.     {
  8128.     clear_var(retvar);
  8129.     retvar->var_type = VAR_NUMBER;
  8130.     retvar->var_val.var_number = -1;
  8131.     }
  8132.     did_emsg |= save_did_emsg;
  8133.     current_funccal = save_fcp;
  8134.  
  8135.     var_clear(&fc.l_vars);        /* free all local variables */
  8136.     --depth;
  8137. }
  8138.  
  8139. /*
  8140.  * Save the current function call pointer, and set it to NULL.
  8141.  * Used when executing autocommands and for ":source".
  8142.  */
  8143.     void *
  8144. save_funccal()
  8145. {
  8146.     struct funccall *fc;
  8147.  
  8148.     fc = current_funccal;
  8149.     current_funccal = NULL;
  8150.     return (void *)fc;
  8151. }
  8152.  
  8153.     void
  8154. restore_funccal(fc)
  8155.     void *fc;
  8156. {
  8157.     current_funccal = (struct funccall *)fc;
  8158. }
  8159.  
  8160. /*
  8161.  * ":return [expr]"
  8162.  */
  8163.     void
  8164. ex_return(eap)
  8165.     exarg_T    *eap;
  8166. {
  8167.     char_u    *arg = eap->arg;
  8168.     var        retvar;
  8169.     char_u    *p;
  8170.  
  8171.     if (current_funccal == NULL)
  8172.     {
  8173.     EMSG(_("E133: :return not inside a function"));
  8174.     return;
  8175.     }
  8176.  
  8177.     if (eap->skip)
  8178.     ++emsg_skip;
  8179.     else
  8180.     current_funccal->linenr = -1;
  8181.  
  8182.     if (*arg != NUL && *arg != '|' && *arg != '\n')
  8183.     {
  8184.     p = arg;
  8185.     if (eval1(&arg, &retvar, !eap->skip) != FAIL)
  8186.     {
  8187.         if (!eap->skip)
  8188.         {
  8189.         clear_var(current_funccal->retvar);
  8190.         *current_funccal->retvar = retvar;
  8191.         }
  8192.         else
  8193.         clear_var(&retvar);
  8194.     }
  8195.     else
  8196.         EMSG2(_(e_invexpr2), p);
  8197.     }
  8198.  
  8199.     /* when skipping, advance to the next command in this line.  When not
  8200.      * skipping, ignore the rest of the line.  Following lines will be ignored
  8201.      * by get_func_line(). */
  8202.     if (eap->skip)
  8203.     {
  8204.     --emsg_skip;
  8205.     eap->nextcmd = check_nextcmd(arg);
  8206.     }
  8207.     else
  8208.     eap->nextcmd = NULL;
  8209. }
  8210.  
  8211. /*
  8212.  * Get next function line.
  8213.  * Called by do_cmdline() to get the next line.
  8214.  * Returns allocated string, or NULL for end of function.
  8215.  */
  8216. /* ARGSUSED */
  8217.     char_u *
  8218. get_func_line(c, cookie, indent)
  8219.     int        c;            /* not used */
  8220.     void    *cookie;
  8221.     int        indent;        /* not used */
  8222. {
  8223.     struct funccall    *fcp = (struct funccall *)cookie;
  8224.     char_u        *retval;
  8225.     garray_T        *gap;  /* growarray with function lines */
  8226.  
  8227.     /* If breakpoints have been added/deleted need to check for it. */
  8228.     if (fcp->dbg_tick != debug_tick)
  8229.     {
  8230.     fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
  8231.                                    sourcing_lnum);
  8232.     fcp->dbg_tick = debug_tick;
  8233.     }
  8234.  
  8235.     gap = &fcp->func->lines;
  8236.     if ((fcp->func->flags & FC_ABORT) && did_emsg)
  8237.     retval = NULL;
  8238.     else if (fcp->linenr < 0 || fcp->linenr >= gap->ga_len)
  8239.     retval = NULL;
  8240.     else
  8241.     {
  8242.     retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
  8243.     sourcing_lnum = fcp->linenr;
  8244.     }
  8245.  
  8246.     if (p_verbose >= 12 && retval == NULL)
  8247.     {
  8248.     ++no_wait_return;
  8249.     msg_scroll = TRUE;        /* always scroll up, don't overwrite */
  8250.     if (fcp->retvar->var_type == VAR_NUMBER)
  8251.         smsg((char_u *)_("%s returning #%ld"), sourcing_name,
  8252.                        (long)fcp->retvar->var_val.var_number);
  8253.     else if (fcp->retvar->var_type == VAR_STRING)
  8254.         smsg((char_u *)_("%s returning \"%s\""), sourcing_name,
  8255.                          get_var_string(fcp->retvar));
  8256.     msg_puts((char_u *)"\n");   /* don't overwrite this either */
  8257.     cmdline_row = msg_row;
  8258.     --no_wait_return;
  8259.     }
  8260.  
  8261.     /* Did we encounter a breakpoint? */
  8262.     if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
  8263.     {
  8264.     dbg_breakpoint(fcp->func->name, sourcing_lnum);
  8265.     /* Find next breakpoint. */
  8266.     fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
  8267.                                    sourcing_lnum);
  8268.     fcp->dbg_tick = debug_tick;
  8269.     }
  8270.  
  8271.     return retval;
  8272. }
  8273.  
  8274. /*
  8275.  * Return TRUE if the currently active function should be ended, because a
  8276.  * return was encountered or an error occured.  Used inside a ":while".
  8277.  */
  8278.     int
  8279. func_has_ended(cookie)
  8280.     void    *cookie;
  8281. {
  8282.     struct funccall  *fcp = (struct funccall *)cookie;
  8283.  
  8284.     return (((fcp->func->flags & FC_ABORT) && did_emsg) || fcp->linenr < 0);
  8285. }
  8286.  
  8287. /*
  8288.  * return TRUE if cookie indicates a function which "abort"s on errors.
  8289.  */
  8290.     int
  8291. func_has_abort(cookie)
  8292.     void    *cookie;
  8293. {
  8294.     return ((struct funccall *)cookie)->func->flags & FC_ABORT;
  8295. }
  8296.  
  8297. #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
  8298. typedef enum
  8299. {
  8300.     VAR_FLAVOUR_DEFAULT,
  8301.     VAR_FLAVOUR_SESSION,
  8302.     VAR_FLAVOUR_VIMINFO
  8303. } var_flavour_T;
  8304.  
  8305. static var_flavour_T var_flavour __ARGS((char_u *varname));
  8306.  
  8307.     static var_flavour_T
  8308. var_flavour(varname)
  8309.     char_u *varname;
  8310. {
  8311.     char_u *p = varname;
  8312.  
  8313.     if (ASCII_ISUPPER(*p))
  8314.     {
  8315.     while (*(++p))
  8316.         if (ASCII_ISLOWER(*p))
  8317.         return VAR_FLAVOUR_SESSION;
  8318.     return VAR_FLAVOUR_VIMINFO;
  8319.     }
  8320.     else
  8321.     return VAR_FLAVOUR_DEFAULT;
  8322. }
  8323. #endif
  8324.  
  8325. #if defined(FEAT_VIMINFO) || defined(PROTO)
  8326. /*
  8327.  * Restore global vars that start with a capital from the viminfo file
  8328.  */
  8329.     int
  8330. read_viminfo_varlist(virp, writing)
  8331.     vir_T    *virp;
  8332.     int        writing;
  8333. {
  8334.     char_u    *tab;
  8335.     int        is_string = FALSE;
  8336.     VAR        varp = NULL;
  8337.     char_u    *val;
  8338.  
  8339.     if (!writing && (find_viminfo_parameter('!') != NULL))
  8340.     {
  8341.     tab = vim_strchr(virp->vir_line + 1, '\t');
  8342.     if (tab != NULL)
  8343.     {
  8344.         *tab++ = '\0';    /* isolate the variable name */
  8345.         if (*tab == 'S')    /* string var */
  8346.         is_string = TRUE;
  8347.  
  8348.         tab = vim_strchr(tab, '\t');
  8349.         if (tab != NULL)
  8350.         {
  8351.         /* create a nameless variable to hold the value */
  8352.         if (is_string)
  8353.         {
  8354.             val = viminfo_readstring(virp,
  8355.                        (int)(tab - virp->vir_line + 1), TRUE);
  8356.             if (val != NULL)
  8357.             varp = alloc_string_var(val);
  8358.         }
  8359.         else
  8360.         {
  8361.             varp = alloc_var();
  8362.             if (varp != NULL)
  8363.             {
  8364.             varp->var_type = VAR_NUMBER;
  8365.             varp->var_val.var_number = atol((char *)tab + 1);
  8366.             }
  8367.         }
  8368.         /* assign the value to the variable */
  8369.         if (varp != NULL)
  8370.         {
  8371.             set_var(virp->vir_line + 1, varp);
  8372.             free_var(varp);
  8373.         }
  8374.         }
  8375.     }
  8376.     }
  8377.  
  8378.     return viminfo_readline(virp);
  8379. }
  8380.  
  8381. /*
  8382.  * Write global vars that start with a capital to the viminfo file
  8383.  */
  8384.     void
  8385. write_viminfo_varlist(fp)
  8386.     FILE    *fp;
  8387. {
  8388.     garray_T    *gap = &variables;        /* global variable */
  8389.     VAR        this_var;
  8390.     int        i;
  8391.  
  8392.     if (find_viminfo_parameter('!') == NULL)
  8393.     return;
  8394.  
  8395.     fprintf(fp, _("\n# global variables:\n"));
  8396.     for (i = gap->ga_len; --i >= 0; )
  8397.     {
  8398.     this_var = &VAR_GAP_ENTRY(i, gap);
  8399.     if (this_var->var_name != NULL
  8400.         && var_flavour(this_var->var_name) == VAR_FLAVOUR_VIMINFO)
  8401.     {
  8402.         fprintf(fp, "!%s\t%s\t", this_var->var_name,
  8403.               (this_var->var_type == VAR_STRING) ? "STR" : "NUM");
  8404.         viminfo_writestring(fp, get_var_string(this_var));
  8405.     }
  8406.     }
  8407. }
  8408. #endif
  8409.  
  8410. #if defined(FEAT_SESSION) || defined(PROTO)
  8411.     int
  8412. store_session_globals(fd)
  8413.     FILE    *fd;
  8414. {
  8415.     garray_T    *gap = &variables;        /* global variable */
  8416.     VAR        this_var;
  8417.     int        i;
  8418.     char_u    *p;
  8419.  
  8420.     for (i = gap->ga_len; --i >= 0; )
  8421.     {
  8422.     this_var = &VAR_GAP_ENTRY(i, gap);
  8423.     if (this_var->var_name != NULL)
  8424.     {
  8425.         if (var_flavour(this_var->var_name) == VAR_FLAVOUR_SESSION)
  8426.         {
  8427.         p = vim_strsave_escaped(get_var_string(this_var),
  8428.                                 (char_u *)"\\\"");
  8429.         if ((fprintf(fd, "let %s = %c%s%c",
  8430.                 this_var->var_name,
  8431.                 (this_var->var_type == VAR_STRING) ? '"' : ' ',
  8432.                 p,
  8433.                 (this_var->var_type == VAR_STRING) ? '"' : ' ') < 0)
  8434.             || put_eol(fd) == FAIL)
  8435.         {
  8436.             vim_free(p);
  8437.             return FAIL;
  8438.         }
  8439.         vim_free(p);
  8440.         }
  8441.  
  8442.     }
  8443.     }
  8444.     return OK;
  8445. }
  8446. #endif
  8447.  
  8448. # if defined(FEAT_MBYTE) || defined(PROTO)
  8449.     int
  8450. eval_charconvert(enc_from, enc_to, fname_from, fname_to)
  8451.     char_u    *enc_from;
  8452.     char_u    *enc_to;
  8453.     char_u    *fname_from;
  8454.     char_u    *fname_to;
  8455. {
  8456.     int        err = FALSE;
  8457.  
  8458.     set_vim_var_string(VV_CC_FROM, enc_from, -1);
  8459.     set_vim_var_string(VV_CC_TO, enc_to, -1);
  8460.     set_vim_var_string(VV_FNAME_IN, fname_from, -1);
  8461.     set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
  8462.     if (eval_to_bool(p_ccv, &err, NULL, FALSE))
  8463.     err = TRUE;
  8464.     set_vim_var_string(VV_CC_FROM, NULL, -1);
  8465.     set_vim_var_string(VV_CC_TO, NULL, -1);
  8466.     set_vim_var_string(VV_FNAME_IN, NULL, -1);
  8467.     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
  8468.  
  8469.     if (err)
  8470.     return FAIL;
  8471.     return OK;
  8472. }
  8473. # endif
  8474.  
  8475. # if defined(FEAT_POSTSCRIPT) || defined(PROTO)
  8476.     int
  8477. eval_printexpr(fname, args)
  8478.     char_u    *fname;
  8479.     char_u    *args;
  8480. {
  8481.     int        err = FALSE;
  8482.  
  8483.     set_vim_var_string(VV_FNAME_IN, fname, -1);
  8484.     set_vim_var_string(VV_CMDARG, args, -1);
  8485.     if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
  8486.     err = TRUE;
  8487.     set_vim_var_string(VV_FNAME_IN, NULL, -1);
  8488.     set_vim_var_string(VV_CMDARG, NULL, -1);
  8489.  
  8490.     if (err)
  8491.     {
  8492.     mch_remove(fname);
  8493.     return FAIL;
  8494.     }
  8495.     return OK;
  8496. }
  8497. # endif
  8498.  
  8499. # if defined(FEAT_DIFF) || defined(PROTO)
  8500.     void
  8501. eval_diff(origfile, newfile, outfile)
  8502.     char_u    *origfile;
  8503.     char_u    *newfile;
  8504.     char_u    *outfile;
  8505. {
  8506.     int        err = FALSE;
  8507.  
  8508.     set_vim_var_string(VV_FNAME_IN, origfile, -1);
  8509.     set_vim_var_string(VV_FNAME_NEW, newfile, -1);
  8510.     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
  8511.     (void)eval_to_bool(p_dex, &err, NULL, FALSE);
  8512.     set_vim_var_string(VV_FNAME_IN, NULL, -1);
  8513.     set_vim_var_string(VV_FNAME_NEW, NULL, -1);
  8514.     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
  8515. }
  8516.  
  8517.     void
  8518. eval_patch(origfile, difffile, outfile)
  8519.     char_u    *origfile;
  8520.     char_u    *difffile;
  8521.     char_u    *outfile;
  8522. {
  8523.     int        err;
  8524.  
  8525.     set_vim_var_string(VV_FNAME_IN, origfile, -1);
  8526.     set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
  8527.     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
  8528.     (void)eval_to_bool(p_pex, &err, NULL, FALSE);
  8529.     set_vim_var_string(VV_FNAME_IN, NULL, -1);
  8530.     set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
  8531.     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
  8532. }
  8533. # endif
  8534.  
  8535. #endif /* FEAT_EVAL */
  8536.  
  8537. #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
  8538.  
  8539. /*
  8540.  * Adjust a filename, according to a string of modifiers.
  8541.  * *fnamep must be NUL terminated when called.  When returning, the length is
  8542.  * determined by *fnamelen.
  8543.  * Returns valid flags.
  8544.  * When there is an error, *fnamep is set to NULL.
  8545.  */
  8546.     int
  8547. modify_fname(src, usedlen, fnamep, bufp, fnamelen)
  8548.     char_u    *src;        /* string with modifiers */
  8549.     int        *usedlen;    /* characters after src that are used */
  8550.     char_u    **fnamep;    /* file name so far */
  8551.     char_u    **bufp;        /* buffer for allocated file name or NULL */
  8552.     int        *fnamelen;    /* length of fnamep */
  8553. {
  8554.     int        valid = 0;
  8555.     char_u    *tail;
  8556.     char_u    *s, *p;
  8557.     char_u    dirname[MAXPATHL];
  8558.     int        c;
  8559.  
  8560. repeat:
  8561.     /* ":p" - full path/file_name */
  8562.     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
  8563.     {
  8564.     valid |= VALID_PATH;
  8565.     *usedlen += 2;
  8566.     /* FullName_save() is slow, don't use it when not needed. */
  8567.     if (!vim_isAbsName(*fnamep))
  8568.     {
  8569.         *fnamep = FullName_save(*fnamep, FALSE);
  8570.         vim_free(*bufp);    /* free any allocated file name */
  8571.         *bufp = *fnamep;
  8572.         if (*fnamep == NULL)
  8573.         return -1;
  8574.     }
  8575.     /* Append a path separator to a directory. */
  8576.     if (mch_isdir(*fnamep))
  8577.     {
  8578.         /* Make room for one or two extra characters. */
  8579.         *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
  8580.         vim_free(*bufp);    /* free any allocated file name */
  8581.         *bufp = *fnamep;
  8582.         if (*fnamep == NULL)
  8583.         return -1;
  8584.         add_pathsep(*fnamep);
  8585.     }
  8586.     }
  8587.  
  8588.     /* ":." - path relative to the current directory */
  8589.     /* ":~" - path relative to the home directory */
  8590.     while (src[*usedlen] == ':' && ((c = src[*usedlen + 1]) == '.' || c == '~'))
  8591.     {
  8592.     *usedlen += 2;
  8593.     /* Need full path first (use expand_env() to remove a "~/") */
  8594.     if (c == '.' && **fnamep == '~')
  8595.         p = expand_env_save(*fnamep);
  8596.     else
  8597.         p = FullName_save(*fnamep, FALSE);
  8598.     if (p != NULL)
  8599.     {
  8600.         if (c == '.')
  8601.         {
  8602.         mch_dirname(dirname, MAXPATHL);
  8603.         s = shorten_fname(p, dirname);
  8604.         if (s != NULL)
  8605.         {
  8606.             *fnamep = s;
  8607.             vim_free(*bufp);    /* free any allocated file name */
  8608.             *bufp = p;
  8609.         }
  8610.         else
  8611.             vim_free(p);
  8612.         }
  8613.         else
  8614.         {
  8615.         home_replace(NULL, p, dirname, MAXPATHL, TRUE);
  8616.         /* Only replace it when it starts with '~' */
  8617.         if (*dirname == '~')
  8618.         {
  8619.             s = vim_strsave(dirname);
  8620.             if (s != NULL)
  8621.             {
  8622.             *fnamep = s;
  8623.             vim_free(*bufp);
  8624.             *bufp = s;
  8625.             }
  8626.         }
  8627.         vim_free(p);
  8628.         }
  8629.     }
  8630.     }
  8631.  
  8632.     tail = gettail(*fnamep);
  8633.     *fnamelen = (int)STRLEN(*fnamep);
  8634.  
  8635.     /* ":h" - head, remove "/file_name", can be repeated  */
  8636.     /* Don't remove the first "/" or "c:\" */
  8637.     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
  8638.     {
  8639.     valid |= VALID_HEAD;
  8640.     *usedlen += 2;
  8641.     s = get_past_head(*fnamep);
  8642.     while (tail > s && vim_ispathsep(tail[-1]))
  8643.         --tail;
  8644.     *fnamelen = (int)(tail - *fnamep);
  8645. #ifdef VMS
  8646.     if (*fnamelen > 0)
  8647.         *fnamelen += 1; /* the path separator is part of the path */
  8648. #endif
  8649.     while (tail > s && !vim_ispathsep(tail[-1]))
  8650.         --tail;
  8651.     }
  8652.  
  8653.     /* ":t" - tail, just the basename */
  8654.     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
  8655.     {
  8656.     *usedlen += 2;
  8657.     *fnamelen -= (int)(tail - *fnamep);
  8658.     *fnamep = tail;
  8659.     }
  8660.  
  8661.     /* ":e" - extension, can be repeated */
  8662.     /* ":r" - root, without extension, can be repeated */
  8663.     while (src[*usedlen] == ':'
  8664.         && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
  8665.     {
  8666.     /* find a '.' in the tail:
  8667.      * - for second :e: before the current fname
  8668.      * - otherwise: The last '.'
  8669.      */
  8670.     if (src[*usedlen + 1] == 'e' && *fnamep > tail)
  8671.         s = *fnamep - 2;
  8672.     else
  8673.         s = *fnamep + *fnamelen - 1;
  8674.     for ( ; s > tail; --s)
  8675.         if (s[0] == '.')
  8676.         break;
  8677.     if (src[*usedlen + 1] == 'e')        /* :e */
  8678.     {
  8679.         if (s > tail)
  8680.         {
  8681.         *fnamelen += (int)(*fnamep - (s + 1));
  8682.         *fnamep = s + 1;
  8683. #ifdef VMS
  8684.         /* cut version from the extension */
  8685.         s = *fnamep + *fnamelen - 1;
  8686.         for ( ; s > *fnamep; --s)
  8687.             if (s[0] == ';')
  8688.             break;
  8689.         if (s > *fnamep)
  8690.             *fnamelen = s - *fnamep;
  8691. #endif
  8692.         }
  8693.         else if (*fnamep <= tail)
  8694.         *fnamelen = 0;
  8695.     }
  8696.     else                /* :r */
  8697.     {
  8698.         if (s > tail)    /* remove one extension */
  8699.         *fnamelen = (int)(s - *fnamep);
  8700.     }
  8701.     *usedlen += 2;
  8702.     }
  8703.  
  8704.     /* ":s?pat?foo?" - substitute */
  8705.     /* ":gs?pat?foo?" - global substitute */
  8706.     if (src[*usedlen] == ':'
  8707.         && (src[*usedlen + 1] == 's'
  8708.         || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
  8709.     {
  8710.     char_u        *str;
  8711.     char_u        *pat;
  8712.     char_u        *sub;
  8713.     int        sep;
  8714.     char_u        *flags;
  8715.     int        didit = FALSE;
  8716.  
  8717.     flags = (char_u *)"";
  8718.     s = src + *usedlen + 2;
  8719.     if (src[*usedlen + 1] == 'g')
  8720.     {
  8721.         flags = (char_u *)"g";
  8722.         ++s;
  8723.     }
  8724.  
  8725.     sep = *s++;
  8726.     if (sep)
  8727.     {
  8728.         /* find end of pattern */
  8729.         p = vim_strchr(s, sep);
  8730.         if (p != NULL)
  8731.         {
  8732.         pat = vim_strnsave(s, (int)(p - s));
  8733.         if (pat != NULL)
  8734.         {
  8735.             s = p + 1;
  8736.             /* find end of substitution */
  8737.             p = vim_strchr(s, sep);
  8738.             if (p != NULL)
  8739.             {
  8740.             sub = vim_strnsave(s, (int)(p - s));
  8741.             str = vim_strnsave(*fnamep, *fnamelen);
  8742.             if (sub != NULL && str != NULL)
  8743.             {
  8744.                 *usedlen = (int)(p + 1 - src);
  8745.                 s = do_string_sub(str, pat, sub, flags);
  8746.                 if (s != NULL)
  8747.                 {
  8748.                 *fnamep = s;
  8749.                 *fnamelen = (int)STRLEN(s);
  8750.                 vim_free(*bufp);
  8751.                 *bufp = s;
  8752.                 didit = TRUE;
  8753.                 }
  8754.             }
  8755.             vim_free(sub);
  8756.             vim_free(str);
  8757.             }
  8758.             vim_free(pat);
  8759.         }
  8760.         }
  8761.         /* after using ":s", repeat all the modifiers */
  8762.         if (didit)
  8763.         goto repeat;
  8764.     }
  8765.     }
  8766.  
  8767.     return valid;
  8768. }
  8769.  
  8770. /*
  8771.  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
  8772.  * "flags" can be "g" to do a global substitute.
  8773.  * Returns an allocated string, NULL for error.
  8774.  */
  8775.     char_u *
  8776. do_string_sub(str, pat, sub, flags)
  8777.     char_u    *str;
  8778.     char_u    *pat;
  8779.     char_u    *sub;
  8780.     char_u    *flags;
  8781. {
  8782.     int        sublen;
  8783.     regmatch_T    regmatch;
  8784.     int        i;
  8785.     int        do_all;
  8786.     char_u    *tail;
  8787.     garray_T    ga;
  8788.     char_u    *ret;
  8789.     char_u    *save_cpo;
  8790.  
  8791.     /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
  8792.     save_cpo = p_cpo;
  8793.     p_cpo = (char_u *)"";
  8794.  
  8795.     ga_init2(&ga, 1, 200);
  8796.  
  8797.     do_all = (flags[0] == 'g');
  8798.  
  8799.     regmatch.rm_ic = p_ic;
  8800.     regmatch.regprog = vim_regcomp(pat, TRUE);
  8801.     if (regmatch.regprog != NULL)
  8802.     {
  8803.     tail = str;
  8804.     while (vim_regexec(®match, str, (colnr_T)(tail - str)))
  8805.     {
  8806.         /*
  8807.          * Get some space for a temporary buffer to do the substitution
  8808.          * into.  It will contain:
  8809.          * - The text up to where the match is.
  8810.          * - The substituted text.
  8811.          * - The text after the match.
  8812.          */
  8813.         sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE);
  8814.         if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
  8815.                 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
  8816.         {
  8817.         ga_clear(&ga);
  8818.         break;
  8819.         }
  8820.  
  8821.         /* copy the text up to where the match is */
  8822.         i = (int)(regmatch.startp[0] - tail);
  8823.         mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
  8824.         /* add the substituted text */
  8825.         (void)vim_regsub(®match, sub, (char_u *)ga.ga_data
  8826.                       + ga.ga_len + i, TRUE, TRUE, FALSE);
  8827.         ga.ga_len += i + sublen - 1;
  8828.         ga.ga_room -= i + sublen - 1;
  8829.         /* avoid getting stuck on a match with an empty string */
  8830.         if (tail == regmatch.endp[0])
  8831.         {
  8832.         if (*tail == NUL)
  8833.             break;
  8834.         *((char_u *)ga.ga_data + ga.ga_len) = *tail++;
  8835.         ++ga.ga_len;
  8836.         --ga.ga_room;
  8837.         }
  8838.         else
  8839.         {
  8840.         tail = regmatch.endp[0];
  8841.         if (*tail == NUL)
  8842.             break;
  8843.         }
  8844.         if (!do_all)
  8845.         break;
  8846.     }
  8847.  
  8848.     if (ga.ga_data != NULL)
  8849.         STRCPY((char *)ga.ga_data + ga.ga_len, tail);
  8850.  
  8851.     vim_free(regmatch.regprog);
  8852.     }
  8853.  
  8854.     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
  8855.     ga_clear(&ga);
  8856.     p_cpo = save_cpo;
  8857.  
  8858.     return ret;
  8859. }
  8860.  
  8861. #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
  8862.